I'm trying to convert a grayscale image in 24-bit RGB format to a grayscale image in 8-bit format. In other words, input and output should be visually identical, only the number of channels changes. Here's the input image:
The code used to convert it to 8-bit:
File input = new File("input.jpg");
File output = new File("output.jpg");
// Read 24-bit RGB input JPEG.
BufferedImage rgbImage = ImageIO.read(input);
int w = rgbImage.getWidth();
int h = rgbImage.getHeight();
// Create 8-bit gray output image from input.
BufferedImage grayImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
int[] rgbArray = rgbImage.getRGB(0, 0, w, h, null, 0, w);
grayImage.setRGB(0, 0, w, h, rgbArray, 0, w);
// Save output.
ImageIO.write(grayImage, "jpg", output);
And here's the output image:
As you can see, there's a slight difference. But they should be identical. For those who can't see it, here's the difference between the two images (when viewed with Difference blending mode in Gimp, full black would indicate no difference). The same problem happens if I use PNG instead for input and output.
After doing grayImage.setRGB
, I tried comparing color values for the same pixel in both images:
int color1 = rgbImage.getRGB(230, 150); // This returns 0xFF6D6D6D.
int color2 = grayImage.getRGB(230, 150); // This also returns 0xFF6D6D6D.
Same color for both. However, if I do the same comparison with the images in Gimp, I get 0xFF6D6D6D
and 0xFF272727
respectively... huge difference.
What's happening here? Is there any way I can obtain an identical 8-bit image from a grayscale 24-bit image? I'm using Oracle JDK 1.8 for the record.