malat
malat

Reputation: 12499

GDI+: Grayscale PNG loaded as PixelFormat32bppARGB

I am trying to load a grayscale PNG file using GDI+ on Windows 7/64bits Pro. However if I use the value returned from Image::GetPixelFormat(), it tells me that the pixelFormat is PixelFormat32bppARGB.

If I convert this PNG to JPG and/or TIFF it now tells me that the pixelFormat is now PixelFormat8bppIndexed.

Looking at the definition for thoses values here, does not tell much. However looking them here, reveals that PixelFormat32bppARGB is in fact the result of (10 | (32 << 8) | PixelFormatAlpha | PixelFormatGDI | PixelFormatCanonical).

My questions are:

  1. What does the following means: PixelFormatCanonical: Is in canonical format ?
  2. I understand that GDI+ is free to represent single component grayscale image as 32bpp ARGB, non-premultiplied alpha, but then how do I check that the underlying representation is actually grayscale ? This will prove useful since I only want to copy a single componentent from the ARGB buffer.

Here are some information from the PNG file using the pnginfo command from a UNIX shell:

$ pnginfo input.png
input.png...
  Image Width: 2492 Image Length: 3508
  Bitdepth (Bits/Sample): 8
  Channels (Samples/Pixel): 1
  Pixel depth (Pixel Depth): 8
  Colour Type (Photometric Interpretation): GRAYSCALE 
  Image filter: Single row per byte filter 
  Interlacing: No interlacing 
  Compression Scheme: Deflate method 8, 32k window
  Resolution: 11811, 11811 (pixels per meter)
  FillOrder: msb-to-lsb
  Byte Order: Network (Big Endian)
  Number of text strings: 0 of 0

This is even an issue with wine implementation of GDI+. Current wine 1.6.2 also think my input PNG really is: PixelFormat8bppIndexed.

Upvotes: 4

Views: 1582

Answers (2)

malat
malat

Reputation: 12499

After trying all possible functions from the GDI+ Image class, I think found the solution. One need to retrieve the flags from the Image and test against ImageFlagsColorSpaceGRAY

For Grayscale PNG:

  • PixelFormat is: PixelFormat32bppARGB
  • ImageFlagsColorSpaceGRAY is set (ImageFlagsColorSpaceRGB is not set)

For RGB PNG:

  • PixelFormat is: PixelFormat24bppRGB
  • ImageFlagsColorSpaceRGB is set (ImageFlagsColorSpaceGRAY is not set)

For RGBA PNG:

  • PixelFormat is: PixelFormat32bppARGB
  • ImageFlagsColorSpaceRGB is set (ImageFlagsColorSpaceGRAY is not set)

Upvotes: 3

Mark Jansen
Mark Jansen

Reputation: 1509

1: The page you linked for the flags is a page from Windows CE, did you confirm that the flags in your Windows SDK are actually the same?

2: The Image::GetPixelFormat tells you the pixel format of the Image object, which does not have to be the same as the PNG file.

At the bottom of the page describing the pixel formats there is a remark:

PixelFormat48bppRGB, PixelFormat64bppARGB, and PixelFormat64bppPARGB use 16 bits per color component (channel). Windows GDI+ version 1.0 can read 16-bits-per-channel images, but such images are converted to an 8-bits-per-channel format for processing, displaying, and saving.

Upvotes: 0

Related Questions