1

I am trying to convert a BufferedImage to a byte array. I have two conditions. 1. I should not lose the quality of the image. 2. The size of the byte array should be the same as the actual image. I tried a couple of options.

Option 1:

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "png", baos);
        baos.flush();
        byte[] imageBytes = baos.toByteArray();
        baos.close();

Option 2:

        WritableRaster raster = image.getRaster();
        DataBufferByte data   = (DataBufferByte) raster.getDataBuffer();
        byte[] imageBytes = data.getData();

Both these options increase the size of the image (more than twofold for large images).

Appreciate any help. Thanks!

home
  • 12,468
  • 5
  • 46
  • 54
sure_render
  • 148
  • 2
  • 7
  • 1
    I've added the `java` tag. Hope this is correct (seems to)... – home Jan 20 '12 at 05:48
  • How do you define the size of the image? The size of a file which contains that image? The memory used by the `Image` instance holding it? If it's the former, that depends on the format you're storing it in. If it's the latter, that depends on the implementation. Also, what are the sizes of the `byte[]`s you are creating vs the "size" of the source image? – Jeffrey Jan 20 '12 at 05:59
  • *"The size of the byte array should be the same as the actual image"* That seems a pretty arbitrary requirement. Who specified it, your teacher? – Andrew Thompson Jan 20 '12 at 06:06
  • @AndrewThompson - I am converting my uploaded image to a byte array to store it on an amazon server. I set a size limit of 5MB for the images being uploaded by the user. So, if an user uploads an image of size 4.99MB, I want the same to be stored on the amazon server. Hope you now see the importance of this requirement. :) – sure_render Jan 20 '12 at 06:09
  • 3
    @sure_render - Why are you even going through a BufferedImage then, if the original file size may already be acceptable? (Why not just pass the bytes as you receive them?) – ziesemer Jan 20 '12 at 06:15
  • @ziesemer - I am not saving the image as it is uploaded. I am cropping the image using getSubImage() before uploading to the amazon server. – sure_render Jan 20 '12 at 06:18
  • @sure_render - You're just dealing with different compression settings / implementations between Java and whatever originally created the images. You may need to tweak the settings that Java is saving the image with. Please see my updated answer for additional details. – ziesemer Jan 20 '12 at 06:19

1 Answers1

2

The PNG format uses lossless data compression, so you shouldn't need to worry about loosing the quality of the image with your option 1.

How are you seeing an increase in the size of the image? I'm sure you know what imageBytes.length is. What are you comparing this to that you're thinking this is twice as large as it should be? (I'm thinking your assumption may be incorrect.)

It is possible that your original source file is just using a higher compression setting than Java is re-compressing it with. You may need to pass some additional parameters into your writer. See how to compress a PNG image using Java for some additional details - specifically the link to http://www.exampledepot.com/egs/javax.imageio/JpegWrite.html.

Community
  • 1
  • 1
ziesemer
  • 27,712
  • 8
  • 86
  • 94
  • I am comparing it to the size of the image file on disk which is 2.65MB, while imageBytes.length gives me a number like 5000000 which is around 5MB. – sure_render Jan 20 '12 at 06:05
  • @sure_render - I assume this file on disk is what you originally loaded the BufferedImage with? If so, what is it's format? It's possible that the original just used a higher compression setting than Java is re-compressing it with. – ziesemer Jan 20 '12 at 06:07
  • Thank you for your suggestions. I am using PNG to ensure the lossless compression with the downside of storing a larger image which was decided to be acceptable. Thanks again! – sure_render Jan 23 '12 at 07:13
  • @sure_render - Just because you're using PNG doesn't mean that you necessarily need to have a larger file size. What was the original file format? If something like JPG, then everything probably makes sense as-is. However, if the original was already PNG, you probably just need to follow the edits to the end of my answer to properly set the compression settings for the PNG export (still lossless, but "try harder" to get a smaller file). – ziesemer Jan 23 '12 at 10:20