Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the pixelformat or bitdepth of TPNGImage

Tags:

delphi

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';
like image 726
Bill Avatar asked Mar 29 '12 16:03

Bill


2 Answers

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;
like image 154
RRUZ Avatar answered Nov 16 '22 12:11

RRUZ


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.

like image 42
Uwe Raabe Avatar answered Nov 16 '22 11:11

Uwe Raabe