重建字节数组图像

发布于 2024-11-06 02:46:15 字数 2024 浏览 4 评论 0原文

我正在尝试接收以字节数组编码的图像。

如果图像不太大,它效果很好,但是当我必须多次读取输入流才能获取所有图像字节时,该行:

BufferedImage img = ImageIO.read(new ByteArrayInputStream(finalData));

返回null

这是我的代码:

byte[]imgSize = new byte[SIZE_OF_LENGTH_ARRAY];
bis.read(imgSize, 0, SIZE_OF_LENGTH_ARRAY);
ByteBuffer bb = ByteBuffer.wrap(imgSize);
int size = bb.getInt();

System.out.println("Client: size="+size);
byte[] tmpData = new byte[size];
System.out.println("tmpData length = "+tmpData.length);
int readen = bis.read(tmpData, 0, tmpData.length);
System.out.println("readen="+readen);

byte[]finalData = new byte[size]; 

if(readen == size){
    finalData = tmpData;
}
else{
    int totalRead = readen;
    int j=1;

    while(totalRead<size){
        System.out.println("-----------append number "+j+"----------");
        System.out.println("totalRead="+totalRead);

        for(int i=0;i<tmpData.length;i++){
            finalData[i]=tmpData[i];
        }

        tmpData = new byte[size-totalRead];
        int tmpRead = bis.read(tmpData, 0, size-totalRead);
        System.out.println("tmpRead="+tmpRead);

        for(int i=0;i<tmpData.length;i++){
            finalData[i+totalRead]=tmpData[i];
        }

        totalRead+=tmpRead;
        j++;
    }
    System.out.println("totalRead final="+totalRead);
}

BufferedImage img = ImageIO.read(new ByteArrayInputStream(finalData));

输出示例是:

---Client: sending mess number 1---
Client: size=31099
tmpData length = 31099
readen=31099
---Client: sending mess number 2---
Client: size=85921
tmpData length = 85921
readen=17520
-----------append number 1----------
totalRead=17520
tmpRead=17520
-----------append number 2----------
totalRead=35040
tmpRead=17520
-----------append number 3----------
totalRead=52560
tmpRead=31408
-----------append number 4----------
totalRead=83968
tmpRead=1953
totalRead final=85921
image null

虽然我很好地读取了 85921 字节,但 ImageIO.Read 生成了一个空图像。

I'm trying to receive an image, coded in a byte array.

It works well if the image is not too big, but when I have to read many times the input stream to get all the image bytes, the line:

BufferedImage img = ImageIO.read(new ByteArrayInputStream(finalData));

returns null.

Here is my code:

byte[]imgSize = new byte[SIZE_OF_LENGTH_ARRAY];
bis.read(imgSize, 0, SIZE_OF_LENGTH_ARRAY);
ByteBuffer bb = ByteBuffer.wrap(imgSize);
int size = bb.getInt();

System.out.println("Client: size="+size);
byte[] tmpData = new byte[size];
System.out.println("tmpData length = "+tmpData.length);
int readen = bis.read(tmpData, 0, tmpData.length);
System.out.println("readen="+readen);

byte[]finalData = new byte[size]; 

if(readen == size){
    finalData = tmpData;
}
else{
    int totalRead = readen;
    int j=1;

    while(totalRead<size){
        System.out.println("-----------append number "+j+"----------");
        System.out.println("totalRead="+totalRead);

        for(int i=0;i<tmpData.length;i++){
            finalData[i]=tmpData[i];
        }

        tmpData = new byte[size-totalRead];
        int tmpRead = bis.read(tmpData, 0, size-totalRead);
        System.out.println("tmpRead="+tmpRead);

        for(int i=0;i<tmpData.length;i++){
            finalData[i+totalRead]=tmpData[i];
        }

        totalRead+=tmpRead;
        j++;
    }
    System.out.println("totalRead final="+totalRead);
}

BufferedImage img = ImageIO.read(new ByteArrayInputStream(finalData));

And an output example is:

---Client: sending mess number 1---
Client: size=31099
tmpData length = 31099
readen=31099
---Client: sending mess number 2---
Client: size=85921
tmpData length = 85921
readen=17520
-----------append number 1----------
totalRead=17520
tmpRead=17520
-----------append number 2----------
totalRead=35040
tmpRead=17520
-----------append number 3----------
totalRead=52560
tmpRead=31408
-----------append number 4----------
totalRead=83968
tmpRead=1953
totalRead final=85921
image null

While I well read 85921 bytes, the ImageIO.Read makes a null image.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

走野 2024-11-13 02:46:15

此行可能会覆盖前一个 while 迭代中的字节:

 while(totalRead<size){
        System.out.println("-----------append number "+j+"----------");
        System.out.println("totalRead="+totalRead);
        //I suspect this is unnecessary and one source of the error
        //this loop would overwrite data from the last iteration's tmpData
        for(int i=0;i<tmpData.length;i++){ 
            finalData[i]=tmpData[i];
        }
        tmpData = new byte[size-totalRead];
        int tmpRead = bis.read(tmpData, 0, size-totalRead);
        System.out.println("tmpRead="+tmpRead);
        for(int i=0;i<tmpData.length;i++){
            finalData[i+totalRead]=tmpData[i];  //append tmpData
        }
        totalRead+=tmpRead;
        j++;
    }

假设您在每次 while 迭代中读取 10 个字节。

在第一次运行中,您将最终数据的所有元素设置为 0,然后读取 10 个字节并将元素设置为 0-最终数据的 9。

在第二次迭代中,您现在循环遍历 tmpData 的内容(字节 0-9),并在读取字节 10-19 并附加它们之前覆盖字节 0-9。 (到目前为止一切顺利)

在第三次迭代中,您将覆盖 tmpData 的内容(现在是第二次迭代中的字节 10-19)并覆盖 FinalData 中的字节 0-9。所以这里有一个错误。

This line might be overwriting bytes from the previous while iteration:

 while(totalRead<size){
        System.out.println("-----------append number "+j+"----------");
        System.out.println("totalRead="+totalRead);
        //I suspect this is unnecessary and one source of the error
        //this loop would overwrite data from the last iteration's tmpData
        for(int i=0;i<tmpData.length;i++){ 
            finalData[i]=tmpData[i];
        }
        tmpData = new byte[size-totalRead];
        int tmpRead = bis.read(tmpData, 0, size-totalRead);
        System.out.println("tmpRead="+tmpRead);
        for(int i=0;i<tmpData.length;i++){
            finalData[i+totalRead]=tmpData[i];  //append tmpData
        }
        totalRead+=tmpRead;
        j++;
    }

Suppose you read 10 bytes in each while iteration.

In the first run you'd set all elements of final data to 0, then read 10 bytes and set elements 0-9 of finalData.

In the second iteration you now loop over the contents of tmpData (which is bytes 0-9) and overwrite bytes 0-9 to before reading bytes 10-19 and appending them. (so far so good)

In the third iteration you lop over the contents of tmpData (which is now bytes 10-19, from the second iteration) and overwrite bytes 0-9 in finalData. So here's one error.

千笙结 2024-11-13 02:46:15

我不知道 bis 是什么,但这一行可能是错误的:

bis.read(imgSize, 0, SIZE_OF_LENGTH_ARRAY);

您应该始终检查读取的返回值。一次读取可以读取的内容少于您指定的内容。

编辑:

这就是您通常从流中读取所有数据的方式:

byte[] buffer = new byte[1024 * 32];
int len = 0;
while ((len = in.read(buffer)) > -1) {
    out.write(buffer, 0, len);
}

编辑2:

但是您为什么不执行以下操作:

ImageIO.read(bis);

I don't know what bis is, but this line is probably wrong:

bis.read(imgSize, 0, SIZE_OF_LENGTH_ARRAY);

You should always check the returned value from a read. A read can read less than you specify.

Edit:

This is how you normally read all data from a stream:

byte[] buffer = new byte[1024 * 32];
int len = 0;
while ((len = in.read(buffer)) > -1) {
    out.write(buffer, 0, len);
}

Edit 2:

But why aren't you doing something like:

ImageIO.read(bis);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文