2012-02-29 5 views
4

TGraphic子孫を含むDelphi TPictureがあるので、ピクセルの色と不透明度を計算する必要があります。 私はクラスごとに異なる実装が必要だと思うし、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; 
+0

TGraphicのすべての子孫が部分(> 1bit)透過性をサポートしているわけではないため、本当に一般的なケースは存在しません。 – OnTheFly

+0

はい、32ビットのビットマップにアルファチャンネルがあります。以下の回答を参照してください。 –

答えて

6

どのようにこのような何かについて:

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; 
+0

偉大な答えは、スポット。遅れて申し訳ありません。 – TheRoadrunner

2

これは、最適化されたが、理解することは簡単ではありません。

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; 
+0

+1をclaryfying 32bit bmpの不透明度のため – TheRoadrunner

関連する問題