java 将 ImageOutputStream 转换为 byte[]
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3507864/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert ImageOutputStream to byte[]
提问by vinaynag
Have been trying to convert ImageOutputStream to byte[] for a while using JAI. Any inputs are appreciated. Thanks.
一直在尝试使用 JAI 将 ImageOutputStream 转换为 byte[] 一段时间。任何输入表示赞赏。谢谢。
Sorry here is the code snippet, I am working on. I had to post it earlier. The problem I am facing is that, I am able to get ByteArrayOutputStream from ImageOutputStream. But it always gives me zero bytes. But if I use a FileOutputStream instead of a ByteArrayOuputStream, I can write into a file which has non zero bytes. :
抱歉,这是代码片段,我正在处理。我不得不提前发布它。我面临的问题是,我能够从 ImageOutputStream 获取 ByteArrayOutputStream。但它总是给我零字节。但是如果我使用 FileOutputStream 而不是 ByteArrayOuputStream,我可以写入一个非零字节的文件。:
File file = new File("C:/TIFFImages/tiff-image.tiff");
FileInputStream in = new FileInputStream(file);
long filelength = file.length();
byte[] bytes = new byte[(int)filelength];
int offset = 0;
int numRead = 0;
while (offset < bytes.length && (numRead=in.read(bytes, offset, bytes.length-offset)) >= 0) {
offset += numRead;
}
if (offset < bytes.length) {
throw new IOException("Could not completely read file "+file.getName());
}
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
RenderedImage src = JAI.create("stream", SeekableStream.wrapInputStream(bais, true));
RenderedOp renderedOp = MedianFilterDescriptor.create(src, MedianFilterDescriptor.MEDIAN_MASK_SQUARE , 1, null);
BufferedImage image = renderedOp.getAsBufferedImage();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
//Instead of baos if I pass a FileOutputStream to the above function. It writes non zero
//bytes to the output file
TIFFImageWriterSpi tiffspi = new TIFFImageWriterSpi();
ImageWriter writer = tiffspi.createWriterInstance();
RenderedImage renderedImage = PlanarImage.wrapRenderedImage(src);
writer.setOutput(ios);
writer.write(image);
writer.write(null,new IIOImage(image, null, null), param);
System.out.println("After tiff ImageIO operations" + baos.toByteArray().length);
Thanks , Vinay
谢谢,维奈
采纳答案by vinaynag
I got the answer for this, which is very close to what Guillaume suggested. Except that no need to write to a temp file in between. The following is the modified code to convert ImageOutputStream to byte[] :
我得到了答案,这与 Guillaume 的建议非常接近。除了不需要写入中间的临时文件。以下是将 ImageOutputStream 转换为 byte[] 的修改代码:
ByteArrayOutputStream baos = new ByteArrayOutputStream(37628);
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
//Instead of baos if I pass a FileOutputStream to the above function. It writes non zero
//bytes to the output file
TIFFImageWriterSpi tiffspi = new TIFFImageWriterSpi();
ImageWriter writer = tiffspi.createWriterInstance();
RenderedImage renderedImage = PlanarImage.wrapRenderedImage(src);
writer.setOutput(ios);
writer.write(image);
writer.write(null,new IIOImage(image, null, null), param);
//Create a ByteArrayInputStream to read that ByteArrayOutputStream and read it from ImageIO
ByteArrayInputStream bai = new ByteArrayInputStream(baos.toByteArray());
RenderedImage out = ImageIO.read(bai);
int size = bos.toByteArray().length;
System.out.println(""+ size);
return bos.toByteArray
回答by sAn
Create ImageOutputStream with ByteArrayOutputStream (instead of FileOutputStream)
使用 ByteArrayOutputStream(而不是 FileOutputStream)创建 ImageOutputStream
ByteArrayOutputStream bos = new ByteArrayOutputStream(255);
ImageOutputStream ios = ImageIO.createImageOutputStream(bos);
// use "ios" for image processing
After image processing is done, image bytes would be available in the "ios" object, but the offset would be positioned at the end of the "ios" object. So we need to position the offset to the beginning of the "ios" object and then read the bytes to write to new ByteArrayOutputStream object. Finally return the toByteArray() from the new object. Like below:
图像处理完成后,图像字节将在“ios”对象中可用,但偏移量将位于“ios”对象的末尾。所以我们需要将偏移量定位到“ios”对象的开头,然后读取字节以写入新的 ByteArrayOutputStream 对象。最后从新对象返回 toByteArray()。像下面这样:
public byte[] getBytes(ImageOutputStream ios) {
ByteArrayOutputStream bos = new ByteArrayOutputStream(255);
byte imageByte;
long counter = 0;
try {
System.out.println("getStreamPosition()[BEFORE]=" + ios.getStreamPosition());
ios.seek(0);
System.out.println("getStreamPosition()[AFTER]=" + ios.getStreamPosition());
} catch (IOException e1) {
e1.printStackTrace();
}
while (true) {
try {
bos.write(ios.readByte());
counter++;
} catch (EOFException e) {
System.out.println("End of Image Stream");
break;
} catch (IOException e) {
System.out.println("Error processing the Image Stream");
break;
}
}
System.out.println("Total bytes read=" + counter);
byte[] retValue = bos.toByteArray();
return retValue;
}
回答by Nick
I'm pretty sure it's because you're not calling ImageOutputStream.flush()at the end of the operation - if the IOS created is a MemoryCacheOutputStream, it seems to require an explicit flush on some ImageIO implementations.
我很确定这是因为您没有ImageOutputStream.flush()在操作结束时调用- 如果创建的 IOS 是 a MemoryCacheOutputStream,它似乎需要对某些 ImageIO 实现进行显式刷新。
回答by The Mighty Rubber Duck
Well, you won't be able to readfrom an outputstream.
好吧,您将无法从输出流中读取。
You should rather try to get an InputStreamfrom your image object and read the necessary data from there.
您应该尝试InputStream从您的图像对象中获取一个并从那里读取必要的数据。
However, if you gave more details about what you are actually trying to achieve we could help you more efficiently. :)
但是,如果您提供更多有关您实际尝试实现的目标的详细信息,我们可以更有效地帮助您。:)
For instance if you are only willing to display the size of the images in bytes, there are several other ways.
例如,如果您只想以字节为单位显示图像的大小,还有其他几种方法。

