Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need to figure which pixels are (completely) transparent

Given a Delphi TPicture containing some TGraphic descendant, I need to figure pixel color and opacity. I think I have to have different implementations for each class, and I think I've got TPngImage covered. Is there any support for transparency in 32bit Bitmaps? Can I address the problem in a more general way than the following?:

procedure GetPixelColorAndTransparency(const Picture: TPicture; X, Y:
    Integer; out Color: TColor; out Opacity: Byte);
var
  Bmp: TBitmap;
begin
  if Picture.Graphic is TPngImage then
  begin
    Opacity := (TPngImage(Picture.Graphic).AlphaScanline[Y]^)[X];
    Color := TPngImage(Picture.Graphic).Pixels[ X, Y ];
  end
  else
  if Picture.Graphic is TBitmap then
  begin
    Color := Picture.Bitmap.Canvas.Pixels[ X, Y ];
    Opacity := 255;
  end
  else
  begin
    Bmp := TBitmap.Create;
    try
      Bmp.Assign(Picture.Graphic);
      Color := Bmp.Canvas.Pixels[ X, Y ];
      Opacity := 255;
    finally
      Bmp.Free;
    end;
  end;
end;
like image 939
TheRoadrunner Avatar asked Feb 21 '23 07:02

TheRoadrunner


1 Answers

How about something like this:

procedure GetPixelColorAndTransparency(const Picture: TPicture; X, Y: Integer; out Color: TColor; out Opacity: Byte); 
type
  PRGBQuadArray = ^TRGBQuadArray;
  TRGBQuadArray = array [Integer] of TRGBQuad;
var 
  Bmp: TBitmap; 
begin 
  if Picture.Graphic is TPngImage then 
  begin 
    with TPngImage(Picture.Graphic) do begin
      Opacity := AlphaScanline[Y]^[X]; 
      Color := Pixels[X, Y]; 
    end;
  end 
  else if Picture.Graphic is TBitmap then 
  begin 
    with Picture.Bitmap do begin
      Color := Canvas.Pixels[X, Y]; 
      if PixelFormat = pf32Bit then begin
        Opacity := PRGBQuadArray(Scanline[Y])^[X].rgbReserved;
      end
      else if Color = TranparentColor then begin
        Opacity := 0;
      end
      else begin
        Opacity := 255; 
      end;
    end;
  end else 
  begin 
    Bmp := TBitmap.Create; 
    try 
      Bmp.Assign(Picture.Graphic); 
      Color := Bmp.Canvas.Pixels[X, Y]; 
      if Color = Bmp.TranparentColor then begin
        Opacity := 0;
      end else begin
        Opacity := 255; 
      end;
    finally 
      Bmp.Free; 
    end; 
  end; 
end; 
like image 156
Remy Lebeau Avatar answered Mar 03 '23 21:03

Remy Lebeau