5

I have this image:

Google image

I'd like to extract the RGB values of this image in an int[]. This is what I've done so far for PNG images:

File f = new File("t.jpg");
BufferedImage img = ImageIO.read(f);
int[] ib = img.getRGB(0, 0, img.getWidth(), img.getHeight(), null, 0, img.getWidth());
Color c = new Color(ib[0]);
System.out.println(c.getRed() + " " + c.getGreen() + " " + c.getBlue());

But here I get this output: 255 128 128 which is not expected since I clearly see (and have verified in several image editors) that the pixel at (0,0) has these values 255 255 255.

I noticed that the type returned by img.getType() is equal to TYPE_3BYTE_BGR so I guess it's a decoding issue happening behind the scene but I can't figure out how to workaround it (or get a clearer understanding of what's happening).

Does anyone would have a suggestion on how to decode this type properly?

aymeric
  • 3,877
  • 2
  • 28
  • 42
  • Why don't you use [`getRGB(int x, int y)`](http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/BufferedImage.html#getRGB(int,%20int)) instead of [`getRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize)`](http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/BufferedImage.html#getRGB(int,%20int,%20int,%20int,%20int[],%20int,%20int))? – Eng.Fouad Aug 14 '12 at 19:55
  • You could convert the image on the file to TYPE_INT_RGB by painting it into a new BufferedImage. But rough & ready, but should work – MadProgrammer Aug 14 '12 at 19:56
  • @Eng.Fouad 1. Because this method is more efficient. 2. Because it's very likely to return the same result (although I didn't test it yet) – aymeric Aug 14 '12 at 20:00
  • Duplicate of http://stackoverflow.com/questions/7816821/how-can-i-get-the-rgb-values-of-a-type-3byte-bgr-image? – martijno Aug 14 '12 at 20:26
  • I'm asking here a question about a specific image + a specific format (JPEG), which is different than the potential duplicate... – aymeric Aug 14 '12 at 20:32
  • There's definitely something weird about this specific image. If I open it in an image editor and save-as, the resulting new file gives the expected pixel values. There must be some encoding difference but that's supposed to be abstracted away by `getRGB()`. I don't know what's going on here, but it's fishy. – Jim Garrison Aug 14 '12 at 21:58
  • Your image's color model likely is not RGB but CMYK, and you'll need to get the RGB data directly into your BufferedImage's raster. Please check out [this question](http://stackoverflow.com/questions/2408613/problem-reading-jpeg-image-using-imageio-readfile-file?rq=1) and it's answer for the likely solution to your problem. – Hovercraft Full Of Eels Aug 15 '12 at 02:42
  • 1
    @HovercraftFullOfEels I thought of that, but the [0,0] pixel value is 0xffff8080, which doesn't produce white in CMYK. I even checked out LAB just in case but that doesn't work either. – Jim Garrison Aug 15 '12 at 06:36

1 Answers1

3

After extensive testing of different solutions, I came out with a bug for the class com.sun.imageio.plugins.jpeg.JPEGImageReader (the class used for the decoding of JPEGs by the ImageIO class).

If I do (recommended by Oracle as this should work with all JVM and by many other threads in SO):

BufferedImage bi = ImageIO.read(new FileInputStream("t.jpg"));

then I get the redish image.

In the other hand, if I do:

JPEGImageDecoder jpegDec = JPEGCodec.createJPEGDecoder(new FileInputStream("t.jpg"));
BufferedImage bi = jpegDec.decodeAsBufferedImage();

then I get the image correctly decoded. (note that com.sun.image.codec.jpeg.JPEGCodec is a specific class of the Sun/Oracle JVM and thus this solution is not portable).

Finally, the other approach that I tried which works is using Toolkit.getDefaultToolkit().createImage(). The image is loaded asynchronously (small disadvantage in my opinion) but at least it could load my image properly. I'm not 100% sure that this last solution is portable on all platforms/JVMs though.

aymeric
  • 3,877
  • 2
  • 28
  • 42