java - 仅保存图像的一部分而不是整个图像,我应该修复什么?

标签 java client-server

刚刚用java编写了一个客户端-服务器程序。 目前,程序的全部工作是:客户端发送屏幕截图,压缩图像,将其发送到服务器,服务器将图像保存在目录中。

由于某种原因,服务器保存的图片是部分的,也就是说服务器端并没有保存所有的截图。

客户端截图

here is the image saved in the server side

相关代码:

private static void screenshot(){

    try {

        BufferedImage image = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
        File compressedImageFile = new File("C:\\Gilad\\Screenshots\\compress.jpg");
        OutputStream os = new FileOutputStream(compressedImageFile);


        Iterator<ImageWriter> writers =  ImageIO.getImageWritersByFormatName("jpg");
        ImageWriter writer = (ImageWriter) writers.next();

        ImageOutputStream ios = ImageIO.createImageOutputStream(os);
        writer.setOutput(ios);

        ImageWriteParam param = writer.getDefaultWriteParam();

        param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        param.setCompressionQuality(1f);
        writer.write(null, new IIOImage(image, null, null), param);

        os.close();
        ios.close();
        writer.dispose();

        Path path = Paths.get("C:\\Images\\Screenshots\\compress.jpg");

        byte[] compressedImage = Files.readAllBytes(path);
        serverThread.sendOutput(compressedImage);   //serverThread is object of type ThreadForServer

    } catch (HeadlessException | AWTException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

从 ThreadForServer 类发送图像:

outputThread = new Thread(new Runnable(){

        @Override
        public void run() {
            byte[] imageAr;
            //ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            int len;
            byte[] lenAr;
            try{
                while(true){
                    if(outputs.isEmpty()) Thread.sleep(10);
                    else{
                        imageAr = outputs.remove();
                        len = imageAr.length;
                        System.out.println("length: " + len);
                        lenAr = ByteBuffer.allocate(4).putInt(len).array();
                        System.out.println("length array: " + lenAr + " " + System.currentTimeMillis());
                        socketOutput.write(lenAr);
                        System.out.println("Image array: " + imageAr + " " + System.currentTimeMillis());
                        socketOutput.write(imageAr);
                        socketOutput.flush();
                        System.out.println("Flushed: " + System.currentTimeMillis());

                    }
                }
            }catch(InterruptedException | IOException e){ e.printStackTrace(); }

        }

    });

服务器端的InputThread:

    inputThread = new Thread(new Runnable(){

        @Override
        public void run() {
            byte[] imageAr;
            byte[] lenAr = new byte[4];
            int len;

            try{
                while(running){
                    System.out.println("Server input thread: " + System.currentTimeMillis());
                    socketInput.read(lenAr);
                    len = ByteBuffer.wrap(lenAr).asIntBuffer().get();
                    System.out.println("length: " + len);
                    imageAr = new byte[len];
                    socketInput.read(imageAr);

                    inputs.add(imageAr);
                    break;

                }
            }catch(IOException e){
                e.printStackTrace();
            }
        }
    });

服务器保存图像:

private static void startClientThreadHandler(ThreadForClient clientThread){
    new Thread(new Runnable(){

        @Override
        public void run() {
            try{
                while(true){
                    byte[] image = clientThread.getInput();
                    if(image == null){
                        Thread.sleep(10);
                        continue;
                    }

                    ByteArrayInputStream in = new ByteArrayInputStream(image);
                    BufferedImage buffImage = ImageIO.read(in);

                    ImageIO.write(buffImage, "jpg", new File(IMAGE_DESTINATION + "\\image" + counter));
                    ++counter;

                }
            }catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }).start();;
}

提前致谢!

最佳答案

这里存在许多潜在的问题。然而,最有可能的是从套接字输入读取时:

                imageAr = new byte[len];
                socketInput.read(imageAr);

InputStream.read(byte[]) 不保证填充提供的byte[]。相反,它返回读取了多少字节。可能需要多次调用 read 才能读取所有字节。

https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html#read-byte:A-

关于java - 仅保存图像的一部分而不是整个图像,我应该修复什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41143452/

相关文章:

java - Hibernate,EHCache,读写缓存,将项目添加到列表

java - 如何通过调用方法更新 JFrame 内容 Pane ?

java - 除了 SimpleDateFormat.parse 之外,是否还需要使用 Regex 来检查日期完整性?

java - 使用 Appium 进行自动化时无法更改我的 Android 应用程序的个人资料图像

java - RMI:检查客户端崩溃

c - 我怎样才能接受多个客户端到 TCP 服务器?

java - 无法从 java.lang.Integer 转换为 R

c++ - 错误 C2064 : term does not evaluate to a function taking 1 arguments - something about threads

java - 如何使用 websocket 检查消息是否真的在 Netty 中传递?

通过命名管道实现的客户端-服务器多线程程序