5

一段时间以来一直在尝试使用 JAI 将 ImageOutputStream 转换为 byte[]。任何输入表示赞赏。谢谢。

抱歉,这是代码片段,我正在处理。我不得不提前发布它。我面临的问题是,我能够从 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);

谢谢,维奈

4

4 回答 4

6

我得到了答案,这与纪尧姆的建议非常接近。除了不需要在两者之间写入临时文件。以下是将 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
于 2010-08-20T00:22:02.707 回答
4

我很确定这是因为您没有ImageOutputStream.flush()在操作结束时调用 - 如果创建的 IOS 是 a MemoryCacheOutputStream,则似乎需要对某些 ​​ImageIO 实现进行显式刷新。

于 2011-01-28T23:38:47.187 回答
3

使用 ByteArrayOutputStream(而不是 FileOutputStream)创建 ImageOutputStream

ByteArrayOutputStream bos = new ByteArrayOutputStream(255);
ImageOutputStream ios = ImageIO.createImageOutputStream(bos);
// use "ios" for image processing

图像处理完成后,图像字节将在“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;
    }
于 2010-12-27T17:26:02.440 回答
0

好吧,您将无法从输出流中读取。

您应该尝试InputStream从图像对象中获取一个并从那里读取必要的数据。

但是,如果您提供有关您实际尝试实现的目标的更多详细信息,我们可以更有效地为您提供帮助。:)

例如,如果您只愿意以字节为单位显示图像的大小,还有其他几种方法。

于 2010-08-18T00:50:42.223 回答