Bill
Bill

Reputation: 3033

How to get the pixelformat or bitdepth of TPNGImage

With Delphi 2010 you can get the pixelformat of a jpg file with

TJPEGImage ( Image.Picture.Graphic ).PixelFormat  

Is there a way to get the pixelformat or bitdepth of TPNGImage?

I tried this but it returns incorrect bitdepth:

 if Lowercase ( ExtractFileExt ( FPath ) ) = '.png' then
   StatusBar1.Panels [ 4 ].Text := ' Color Depth: ' + IntToStr( TPNGImage ( Image.Picture.Graphic ).Header.ColorType ) + '-bit';

Upvotes: 5

Views: 2250

Answers (2)

RRUZ
RRUZ

Reputation: 136391

you must use the BitDepth field

TPNGImage(Image.Picture.Graphic ).Header.BitDepth) 

and using the ColorType field you can wirte a function like this

function BitsForPixel(const AColorType,  ABitDepth: Byte): Integer;
begin
  case AColorType of
    COLOR_GRAYSCALEALPHA: Result := (ABitDepth * 2);
    COLOR_RGB:  Result := (ABitDepth * 3);
    COLOR_RGBALPHA: Result := (ABitDepth * 4);
    COLOR_GRAYSCALE, COLOR_PALETTE:  Result := ABitDepth;
  else
      Result := 0;
  end;
end;

and use like so

procedure TForm72.Button1Click(Sender: TObject);
begin
    ShowMessage(IntToStr( BitsForPixel(
    TPNGImage ( Image1.Picture.Graphic ).Header.ColorType,
    TPNGImage ( Image1.Picture.Graphic ).Header.BitDepth
    )));
end;

Upvotes: 7

Uwe Raabe
Uwe Raabe

Reputation: 47704

As Rodrigo pointed out, Header.BitDepth is the value to use. The pitfall is that you have to interpret it depending on the ColorType. You may find some hints in the comments inside function BytesForPixels in PngImage.pas:

{Calculates number of bytes for the number of pixels using the}
{color mode in the paramenter}
function BytesForPixels(const Pixels: Integer; const ColorType,
  BitDepth: Byte): Integer;
begin
  case ColorType of
    {Palette and grayscale contains a single value, for palette}
    {an value of size 2^bitdepth pointing to the palette index}
    {and grayscale the value from 0 to 2^bitdepth with color intesity}
    COLOR_GRAYSCALE, COLOR_PALETTE:
      Result := (Pixels * BitDepth + 7) div 8;
    {RGB contains 3 values R, G, B with size 2^bitdepth each}
    COLOR_RGB:
      Result := (Pixels * BitDepth * 3) div 8;
    {Contains one value followed by alpha value booth size 2^bitdepth}
    COLOR_GRAYSCALEALPHA:
      Result := (Pixels * BitDepth * 2) div 8;
    {Contains four values size 2^bitdepth, Red, Green, Blue and alpha}
    COLOR_RGBALPHA:
      Result := (Pixels * BitDepth * 4) div 8;
    else
      Result := 0;
  end {case ColorType}
end;

As you see, for ARGB (= COLOR_RGBALPHA) the BitDepth value is taken for each color part plus the alpha value individually. So BitDepth = 8 will result in a 32-bit value for each pixel.

Upvotes: 7

Related Questions