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

时间:2016-12-14 13:08:07

标签: 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();;
}

提前致谢!

2 个答案:

答案 0 :(得分:1)

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

                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-

答案 1 :(得分:0)

代码太多而且代码不够。

首先找出问题所在。检查它是否在客户端(正确捕获图像?),从客户端传输(你发送了所有字节?)还是在服务器上(你收到了所有字节)?

我敢打赌,当您在服务器端执行socketInput.read(imageAr)时,您不会获得所有数据,只会获得部分数据。在获得-1之前,您必须反复阅读。