Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Convert Java Image Object to Byte Array

Posted on 2006-03-27
27
Medium Priority
?
4,238 Views
Last Modified: 2008-01-09
I need to take a java Image object (java.awt.Image) and convert it to a byte array. I need to preserve all of the image information not just the pixels!

Basically I have a database, and I have read the image from the database into a byte array, I have then constructed an Image object from this byte array - this all works fine, I can render the image, manipulate it etc.
But now I need to go the other way and convert the Image object back to a byte array - this doesnt appear to be so easy!

The solution MUST work for both Sun JDK 1.4+ and 1.5+ and MUST NOT rely on any 3rd party libraries unless they are absolutely tiny and open source, although 3rd party libraries are not the prefered method!

The code I had originally found to do this (below) throws an exception at g,drawimage(...), and to be honset I dont understand enough about Java to fix it myself (ths solution does not have to include this code)-

private byte[] convertImageToByteArray(Image img, String MIMEType)
{
            try
              {
                  Iterator iter = ImageIO.getImageWritersByMIMEType(MIMEType);
                  ImageWriter writer = iter.hasNext() ? (ImageWriter) iter.next() : null;
                  ByteArrayOutputStream baos = new ByteArrayOutputStream();
                  ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
                  writer.setOutput(ios);
                  BufferedImage rendImage = null;
                  if(img instanceof BufferedImage)
                  {
                      rendImage = (BufferedImage) img;
                  }
                  else
                  {
                      MediaTracker tracker = new MediaTracker(this);
                      tracker.addImage(img, 0);
                      tracker.waitForAll();
                      rendImage = new BufferedImage(img.getWidth(null), img.getHeight(null), 1);
                      Graphics g = rendImage.createGraphics();
                      g.drawImage(img, 0, 0, null);
                  }
                  writer.write(new IIOImage(rendImage, null, null));
                  writer.dispose();
                  return baos.toByteArray();
              }
            catch(Exception e)
            {
                  e.printStackTrace();//temp
                  return null;
            }
}

0
Comment
Question by:adamretter
  • 10
  • 10
  • 4
24 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 16304735
Please post the exception stack trace
0
 
LVL 92

Expert Comment

by:objects
ID: 16304997
> I need to preserve all of the image information not just the pixels!

what other information specifically do u need?
0
 
LVL 92

Expert Comment

by:objects
ID: 16305042
try:

                     MediaTracker tracker = new MediaTracker(this);
                     tracker.addImage(img, 0);
                     tracker.waitForAll();
                     rendImage = new BufferedImage(img.getWidth(null), img.getHeight(null), 1);
                     Graphics g = rendImage.createGraphics();
                     g.drawImage(img, 0, 0, null);
                     tracker.addImage(rendImage, 1);
                     tracker.waitForAll();
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 86

Expert Comment

by:CEHJ
ID: 16305045
You needn't worry about that. It *will* be preserved (otherwise it wouldn't be possible to reconstitute the image from a file)
0
 
LVL 92

Expert Comment

by:objects
ID: 16305056
And close baos.
0
 

Author Comment

by:adamretter
ID: 16334662
FAO CEHJ, here is the exception -

java.lang.ClassCastException: [I
      at java.awt.image.ColorModel.getAlpha(ColorModel.java:814)
      at java.awt.image.ColorModel.getRGB(ColorModel.java:859)
      at sun.awt.image.ImageRepresentation.convertToRGB(ImageRepresentation.java:271)
      at sun.awt.image.ImageRepresentation.setPixels(ImageRepresentation.java:485)
      at java.awt.image.AreaAveragingScaleFilter.accumPixels(AreaAveragingScaleFilter.java:196)
      at java.awt.image.AreaAveragingScaleFilter.setPixels(AreaAveragingScaleFilter.java:235)
      at sun.awt.image.OffScreenImageSource.sendPixels(OffScreenImageSource.java:84)
      at sun.awt.image.OffScreenImageSource.produce(OffScreenImageSource.java:169)
      at sun.awt.image.OffScreenImageSource.addConsumer(OffScreenImageSource.java:48)
      at sun.awt.image.OffScreenImageSource.startProduction(OffScreenImageSource.java:62)
      at java.awt.image.FilteredImageSource.startProduction(FilteredImageSource.java:166)
      at sun.awt.image.ImageRepresentation.startProduction(ImageRepresentation.java:647)
      at sun.awt.image.ImageRepresentation.drawToBufImage(ImageRepresentation.java:722)
      at sun.java2d.pipe.DrawImage.copyImage(DrawImage.java:883)
      at sun.java2d.pipe.ValidatePipe.copyImage(ValidatePipe.java:168)
      at sun.java2d.SunGraphics2D.drawImage(SunGraphics2D.java:2847)
      at sun.java2d.SunGraphics2D.drawImage(SunGraphics2D.java:2832)
      at org.exist.xquery.modules.image.ScaleFunction$ImageConversion.convertImageToByteArray(ScaleFunction.java:266)
0
 

Author Comment

by:adamretter
ID: 16334674
FAO objects,

The code that you propose wont make any difference, because as I mentioned the exception is thrown at g.drawImage() which happends before your suggested changes...
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 16335378
>>FAO CEHJ, here is the exception -

Is that *all* of it?
0
 

Author Comment

by:adamretter
ID: 16335742
It goes lower but there is no point posting that, as it is just the code in existing modules of a collaborative open source project that are known to work. All the code I have written for this is in org.exist.xquery.modules.image.ScaleFunction, everything below can be safely ignored I believe.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 16335787
Are there any exceptions lower down?
0
 
LVL 92

Expert Comment

by:objects
ID: 16336904
Check the color model of your original image, and set the color model of your BufferedImage to match it.
0
 
LVL 92

Expert Comment

by:objects
ID: 16336951
for example if it's rgb with transparency (which it looks like) use:

 rendImage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_ARGB);
0
 

Author Comment

by:adamretter
ID: 16417229
FAO CEHJ - no there are no exceptions further down
0
 

Author Comment

by:adamretter
ID: 16417276
FAO objects -

There is no BufferedImage.TYPE_ARGB, so I have tried -

TYPE_INT_ARGB
TYPE_INT_ARGB_PRE
TYPE_4BYTE_ABGR
TYPE_4BYTE_ABGR_PRE

They still seem to cause the same exception as before.

This function has to work on any image type, be it PNG, JPEG, GIF or BMP etc...
So hardcoding something like that probably wont work for me.

Whats next?
0
 
LVL 92

Expert Comment

by:objects
ID: 16421761
Problem you're going to have is that you cannot determine things like the ColorModel from Image class.
So preserviing all the details of the original image will be difficult. In fact how you are converting the image you're going to lose details of the original image aren't you.

to get the original images color model try:

PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
pg.grabPixels();
ColorModel cm = pg.getColorModel();

you can then use that when creating the new image
or use it to determine whether the image uhas transparency

boolean transparent = cm.hasAlpha();
0
 

Author Comment

by:adamretter
ID: 16425619
FAO Objects -

I think you are going to hold my hand a bit more,

The constructor of BufferedImage will take a ColorModel but it also wants an ImageType, where do I get this imageType from?

Rather than these piecemeal suggestions, What I would really like is a full tested solution here for converting an java.awt.Image to a byte array without loosing any of the image information. Basically I am trying to store a java.awt.Image in a db.

Do I need to increase the points for this? I can offer double the points (1000) for the correct fully working solution...
0
 
LVL 92

Expert Comment

by:objects
ID: 16425672
What exactly is it you don't want to lose, other than the array of pixel values?
Why not just use PixelGrabber to grab the image pixel values as an array.

http://java.sun.com/j2se/1.5.0/docs/api/java/awt/image/PixelGrabber.html

Providing complete solutions is beyond the scope of this site sorry.
0
 

Author Comment

by:adamretter
ID: 16425744
I dont want to loose any data about the image.

I need to be able to store the image in a db, so later I can get it out the db and reconstruct it from a byte array. I have sucessfully written and tested the code for getting an image from a byte array stored in the db, I can retreive the image from the db into an java.awt.Image object and view the Image, no problem.

Now I need the other end of the process, to take a java.awt.Image and convert it in its entirety to a byte array so i can then store if back to the db.

"Providing complete solutions is beyond the scope of this site sorry" - Why? This site is about asking questions and gettings answers,  I think I have had solutions given for previous questions I have asked on this site in the past. All you need do is post the java code in one of these comment boxes that will do the job.

Im offering 1000 points.
0
 
LVL 92

Expert Comment

by:objects
ID: 16425795
Then it sounds like PixelGrabber will meet your needs

int[] pixels = new int[w * h];
PixelGrabber pg = new PixelGrabber(image, 0, 0, w, h, pixels, 0, w);
pg.grabPixels();

pixels will now contain the value of all pixels in the image.
0
 

Author Comment

by:adamretter
ID: 16425969
What about the metadata of the image, I know that at least JPEG's can contain metadata?
0
 
LVL 92

Expert Comment

by:objects
ID: 16431652
> What about the metadata of the image, I know that at least JPEG's can contain metadata?

You've already lost that when u converted to Image class.
If you don't want to lose it then you'll need to store the original image.
0
 

Author Comment

by:adamretter
ID: 16438628
Okay so I have the original image in its entirely stored in the db, I can retreive this from the db as a byte array.

Now the bigger picture is this, I am retreiving this image so that i can Scale it, which is why I was using the java.awt.Image Object, I then want to store the scaled Image back to the db, which is why I was asking how to convert an Image to a byte array. I did not realise that converting from the byte array to a java.awt.Image meant that I would loose additional image information, and if this is the case, how come its still possible to call Image.getProperty("comment"...) ?

Whats my best bet then?
0
 
LVL 92

Accepted Solution

by:
objects earned 2000 total points
ID: 16441070
I'd suggest using BufferedImage instead of Image, it contains a lot more detail about the image.
And will also get rid of the error you are having above.
Sopunds like you may also want to encode the image to a byte array in its original format so you may need to also store what that format is.
0
 

Author Comment

by:adamretter
ID: 16624718
I diagree, this issue has not yet been solved. The answers have been very piecemeal and not really what I asked for. I would like this question to remain open.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this post we will learn different types of Android Layout and some basics of an Android App.
In this post we will learn how to make Android Gesture Tutorial and give different functionality whenever a user Touch or Scroll android screen.
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
Suggested Courses
Course of the Month20 days, 20 hours left to enroll

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question