I'm trying to reliably obtain the RGB values of an image pixel cross-platform.
For my test I am using a jpg image supplied to me by someone else (see Edit - The plot thickens section below).
In C#, I'm doing something similar to the following (where bmpData is a BitmapData object):
PixelData* pScan = (PixelData*)bmpData.Scan0;
...
struct PixelData
{
internal byte r;
internal byte g;
internal byte b;
internal PixelData(byte r, byte g, byte b)
{
this.r = r;
this.g = g;
this.b = b;
}
}
In Java, I have tried the following where image is a BufferedImage object (created from a byte[] read in this utility method: http://docs.oracle.com/javase/7/docs/api/javax/imageio/ImageIO.html#read(java.io.InputStream)):
Raster raster = image.getRaster();
for(x){
for(y){
double[] pixel = raster.getPixel(x, y, new double[3]);
And this:
int rgb = image.getRGB(x, y);
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
And this:
Raster raster = image.getRaster();
int r = raster.getSample(x, y, 0);
int g = raster.getSample(x, y, 1);
int b = raster.getSample(x, y, 2);
With my test image, the results are always as follows. For example, taking the first pixel:
C# Result:
R=16
G=60
B=109
Java Result (in every case):
R=52
G=160
B=102
So, I have three questions:
1. Why are they so wildly different?
2. Is it because I'm doing it wrong?
3. Is there a better way to do it in either case?
Thank you for any help you can offer!
Edit - 2015-10-19 After someone suggested I use an image tool to "pick" the colour of the first pixel, I did so. The values were as follows:
Microsoft Paint:
R=17
G=61
B=110
GIMP:
R=16
G=60
B=109
So my question has changed to:
Why are the RGB values from Java's BufferedImage class so wrong?
Edit - The plot thickens
I exported the image from GIMP and ran it through the same program, and now the RGB figures all match up correctly.
Something in the GIMP export process has changed it so that it now works the same in the Java library.
Now I need to figure out what has changed! Unfortunately I have limited knowledge in this area.
I've checked the alpha precalculations, the ColorModel and ColorSpace. Everything is perceivably the same.
Images (I hope unaltered):
https://www.dropbox.com/s/9pc4nxwdav5s0za/correctRGBs.jpg?dl=0
https://www.dropbox.com/s/fknlj1n4jcuk4pg/incorrectRGBs.jpg?dl=0
Implemented Solution
After Anders' suggestion, I investigated the twelvemonkeys "plugins" first, as it seemed the cleanest solution.
I also noticed that the author had written a plugin to handle tiff files, which was a bonus, as I was previously identifying tiffs by their magic numbers and converting them using the JAI library. No need anymore!
To get this to work I simply added the following gradle dependencies:
compile 'com.twelvemonkeys.imageio:imageio-jpeg:3.1.2'
compile 'com.twelvemonkeys.imageio:imageio-tiff:3.1.2'
Refreshed and ran it again. When it ran again, I could see from the debugger - as well as the results - that the image had been loaded into a BufferedImage object correctly.
The RGB values were then correct too. Thanks!