Необходимо выяснить, какие пиксели (полностью) прозрачны - PullRequest
4 голосов
/ 01 марта 2012

Учитывая Delphi TPicture, содержащий некоторый потомок TGraphic, мне нужно измерить цвет и непрозрачность пикселя. Я думаю, что у меня должны быть разные реализации для каждого класса, и я думаю, что я покрыл TPngImage. Есть ли поддержка прозрачности в 32-битных растровых изображениях? Могу ли я решить проблему в более общем виде, чем указано ниже:

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;

Ответы [ 2 ]

6 голосов
/ 01 марта 2012

Как насчет этого:

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; 
2 голосов
/ 01 марта 2012

Это не оптимизировано, но просто для понимания:

procedure GetPixelColorAndTransparency(const Picture: TPicture; X, Y:
    Integer; out Color: TColor; out Opacity: Byte);
var
  Bmp: TBitmap;
  Color32: Cardinal;
begin
  Bmp := TBitmap.Create;
  try
    Bmp.Assign(Picture.Graphic);
    Color32 := Bmp.Canvas.Pixels[ X, Y ];
    Color := Color32 and $00FFFFFF;
    Opacity := Color32 shr 24;
  finally
    Bmp.Free;
  end;
end;
...