【问题标题】:Socket recieves Images with delay of 1套接字接收延迟为 1 的图像
【发布时间】:2017-05-05 19:02:48
【问题描述】:

我有一个套接字,它通过一个不会关闭的 InputStream 接收图像。我想以这种方式连续发送图像。但是现在收到的图像延迟了 1 张图像(我发送了第二张之后的第一张,发送了第三张之后的第二张,......)。我做错了什么?

服务器

  public static void readImages(InputStream stream) throws IOException    {
     stream = new BufferedInputStream(stream);
     BufferedImage image = null;
     int j = 0;

     while (true) {

        stream.mark(MAX_IMAGE_SIZE);

        ImageInputStream imgStream =  ImageIO.createImageInputStream(stream);
        Iterator<ImageReader> i = ImageIO.getImageReaders(imgStream);
        if (!i.hasNext()) {
            System.out.println("No more image readers");
            break;
        }

        ImageReader reader = i.next();
        reader.setInput(imgStream);

        image = reader.read(0);
        ImageIO.write(image,"jpg",new File("current" + j + ".jpg"));
        System.out.println("Save an image " + j);


        if (image == null) {
            System.out.println("Image is null");
            break;
        }

        long bytesRead = imgStream.getStreamPosition();

        stream.reset();
        stream.skip(bytesRead);
        j++;
    }
}

客户

new Thread(new Runnable() {
            @Override
            public void run() {
                try {

                    OutputStream outputStream = server.getOutputStream();
                    ByteArrayOutputStream stream = new  ByteArrayOutputStream();
                    bitmapToSend =  Bitmap.createScaledBitmap(bitmapToSend, 900, 800, true);
                    bitmapToSend.compress(Bitmap.CompressFormat.JPEG,  100, stream);
                    byte[] byteArray = stream.toByteArray();
                    outputStream.write(byteArray);
                    outputStream.flush();
                } catch (IOException e) {
                    System.out.println("Socket not created");
                    e.printStackTrace();
                }
            }
        }).start();

注意我没有关闭客户端的输出流,所以我可以一直发送图片。

【问题讨论】:

  • 您使用什么代码发送第二张或第三张图片?
  • 我用相机拍照(bufferedImage)并将其分配给bitmapToSend。剩下的就是“客户端”sn-p
  • 是的,这已经在氰化物的答案中实现了,但是有一个问题。我把它放在下面的评论中。

标签: android sockets stream bufferedimage


【解决方案1】:

对于套接字流,使用 ImageIO.getImageReaders(imgStream) 似乎不合逻辑,因为它可能希望所有图像一次可用。这可能是您延迟的原因。

其次,对于解压缩图像,有一个简单的方法 BitmapFactory.decodeStream()。

第三,由于客户端已经创建了“JPG”格式,服务器只需要存储它。您只需要在开始时发送字节数,在发送完所有文件后发送零。

客户:

new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                ByteArrayOutputStream memoryStream = new  ByteArrayOutputStream();
                Bitmap bitmapToSend =
                    Bitmap.createScaledBitmap(bitmapToSend, 900, 800, true);
                bitmapToSend.compress(
                     Bitmap.CompressFormat.JPEG,100, memoryStream);
                byte[] byteArray = memoryStream.toByteArray();
                memoryStream = null;

                DataOutputStream outputStream = 
                          new DataOutputStream(server.getOutputStream());
                outputStream.writeInt(byteArray.length);
                outputStream.write(byteArray);
                outputStream.flush();
            } catch (IOException e) {
                System.out.println("Socket not created");
                e.printStackTrace();
            }
        }
    }).start();

服务器:

public static void readImages(InputStream stream) {

    DataInputStream imgInput = new DataInputStream(stream);
    int index = 0;
    int byteLength;

    try {
        while ((byteLength = imgInput.readInt())>0) {

            byte[] buffer = new byte[byteLength];
            imgInput.readFully(buffer);

            OutputStream imgOutput = new FileOutputStream("current" + (index++) + ".jpg");
            imgOutput.write(buffer);
            imgOutput.close();
        }
    } catch (IOException ex) {
        // .............
    } finally {
        try {
            imgInput.close();
        } catch (IOException ex1) {
            //...........
        }
    }

}

【讨论】:

  • 我将这些方法插入到我的代码中,但现在它发送了第一个图像并停在那里。图像仅在顶部两行中填充了“有效”像素,其余的只是灰色。这可能是 'imgInput.readInt()' 的问题吗?
  • 所以图像重复第二行的最后一个有效像素。当我通过 ImageIO 打印图像时,我得到了完整的图像。所以我认为这与保存while循环的内部有关
  • imgInput.read(buffer) 应该是imgInput.readFully(buffer) (或者您可以实现一些使用较小缓冲区的“更智能”的读/写循环)。无论如何,不​​要依赖imgInput.read(buffer) 来完全填满缓冲区。
猜你喜欢
  • 2013-03-13
  • 2018-10-12
  • 2014-06-05
  • 1970-01-01
  • 1970-01-01
  • 2017-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多