需要弄清楚哪些像素是(完全)透明的
Posted
技术标签:
【中文标题】需要弄清楚哪些像素是(完全)透明的【英文标题】:Need to figure which pixels are (completely) transparent 【发布时间】:2012-03-19 09:40:42 【问题描述】:给定一个包含一些 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;
【问题讨论】:
不存在真正的一般情况,因为并非所有 TGraphic 后代都支持部分 (>1bit) 透明度。 是的,32 位位图有一个 Alpha 通道。请参阅下面的答案。 【参考方案1】:这样的事情怎么样:
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】:未优化但简单易懂:
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;
【讨论】:
以上是关于需要弄清楚哪些像素是(完全)透明的的主要内容,如果未能解决你的问题,请参考以下文章