Problem with PNG Image Java ImageIO Grayscale

I have an image in grayscale ("Lena") with which I want to experiment. I got it as a 512x512 PNG file with 216 shades of gray.

What happens when I read it using Java ImageIO, for example:

    String name = args[0];
    File fi = new File(name);
    BufferedImage img = ImageIO.read(fi);

I get a BufferedImage with just 154 colors ! I only realized this because my processed images looked yellow, without deep black.

Even more annoying, when I use XnView, it converts PNG to GIF, which in this case is a lossless procedure, read the GIF with the above code, I get all 216 colors in my BufferedImage.

Is there any documentation or description of what happens to my PNG when ImageIO reads it? Are there any settings to fix this? I did these experiments on the fairly recent JDK1.8. I just lost confidence in Java PNG support, and later I will use color PNG.

+2
source share
2 answers

Welcome to the Java "great" world of implicit color management!

Java ( , ImageIO) sRGB, , , . , , ImageIO , , ICC ( ), Java "" ICC WhitePoint = D50, Gamma = 1.0, .

, (, img.getRGB() - ?), sRGB ( Java Windows).

sRGB, ~ 2.2 (sRGB- , 2.2 ), - (1/Gamma) = 2.2 , () "", (b) - - 256 256 .

, BufferedImage -: a) :

ColorSpace colorSpace = img.getColorModel().getColorSpace();
if ( colorSpace instanceof ICC_ColorSpace ) {
    ICC_Profile profile = ((ICC_ColorSpace)colorSpace).getProfile();
    if ( profile instanceof ICC_ProfileGray ) {
        float gamma = ((ICC_ProfileGray)profile).getGamma();
        system.out.println("Gray Profile Gamma: "+gamma); // 1.0 !
    }
}

b) -...

//access sRGB values (Colors translated from img ICC profile to sRGB)
System.out.println( "pixel 0,0 value (sRGB): " + Integer.toHexString(img.getRGB(0,0)) ); // getRGB() actually means "getSRGB()"
//access raw raster data, this will give you the uncorrected gray value
//as it is in the image file
Raster raster = image.getRaster();
System.out.println( "pixel 0,0 value (RAW gray value): " + Integer.toHexString(raster.getSample(0,0,0)) );

(0,0) 100% 100% , , sRGB "", , , gray = d1 → sRGB = ffeaeaea ( , , , ).

, , ( , - 1/- 2,2). , Java ICC sRGB R = G = B = grayValue ICC Grey WhitePoint = D50, Gamma = 2.2 ( , Windows). - , sRGB Gamma 2.2.

, GIF: GIF " " ICC, 256- (256 256 ). GIF Java , RGB sRGB.

: , , (gray = raster.getSample(x, y, 0)) sRGB R = = = . .

java PNG: java ImageIO , . , , . , sRGB ( sRGB , , sRGB). , (, AdobeRGB). - , , ImageIO () Gray Profile Gamma = 1.0. , , ImageIO, ABC , , Java. ! : ImageIO , , , . , , , , , , .

+4

- (gamma = 1.0) sRGB (gamma = 1/2.2). GraphicsMagick. Lenna.png, , sRGB, lena.png,

gm convert lena.png -colorspace gray -depth 8 -strip lena-gray.png

lena-gray.png 216

gm convert lena-gray.png -gamma 2.2 -depth 8 -strip lena-gray-gm22.png

lena-gray-gm22.png 154 .

- graphicsmagick ( 1.4) libpng-1.6.17.

, ImageMagick:

identify -verbose file.png | grep Colors

pngcheck -v file.png

, Lenna.png IHDR, sRGB, IDAT IEND, lena-gray.png lena-gray-gm22.png IHDR, IDAT IEND.

+1

Source: https://habr.com/ru/post/1616181/


All Articles