Have been trying to convert ImageOutputStream to byte[] for a while using JAI. Any inputs are appreciated. Thanks.
Sorry here is the code snippet, I am working on. I had to 开发者_C百科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. :
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
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.
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[] :
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
Create ImageOutputStream with ByteArrayOutputStream (instead of FileOutputStream)
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:
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;
}
Well, you won't be able to read from an output stream.
You should rather try to get an InputStream
from your image object and read the necessary data from there.
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.
精彩评论