我正在将PNG图像加载到Delphi-XE2 Update3 FireMonkey HD应用程序中的FMX.Type.TBitmap
。我如何检查加载的PNG图像是否有alpha通道?
目前,如果我加载带有alpha通道的图像,它在Bitmap.Scanline[Y]^[X]
中以$AABBGGRR的形式具有alpha信息。但是,如果我加载没有alpha的PNG图像,则所述记录只有$00BBGGRR条目(AA = 0),就像具有清晰alpha的图像一样。因此问题-如何确定它是RGBA图像与alpha完全透明或它是RGB图像(在这种情况下,我将处理它,使alpha完全不透明)。注意:检查所有像素不是一个选项。
FMX TBitmap没有PixelFormat
属性,也找不到HasAlpha
标志
你可能不喜欢这个。
FMX中的所有位图都是32位的,并且它们是使用操作系统中的代码加载和保存的,这些代码都是32位的。
所以,真正的答案是所有的位图都有一个alpha通道。
但是,你真正想知道的是位图是否使用alpha通道,唯一的方法是遍历每个像素,看看是否有一个alpha通道为<> 255。
我的建议如下(未经测试):
function TBitmap.IsAlpha(Bitmap: TBitmap): Boolean;
var
I, j: Integer;
Bits: PAlphaColorRecArray;
begin
Bits := PAlphaColorRecArray(StartLine);
for j := 0 to Height - 1 do
for I := 0 to Width - 1 do
begin
if Bits[I + (j * Width)].A <> 255 then
begin
Result := True;
EXIT;
end;
end;
Result := False;
end;
下面的函数检查PNG文件是否有透明通道。这很容易,因为主要的PNG头有一个固定的长度,并且数据信息块IHDR
必须是第一个出现的块。
function PngHasAlphaLayer(f: String): Boolean;
var
fs: TFileStream;
colorType: Byte;
begin
fs := TFileStream.Create(f, fmOpenRead);
fs.Position := 25;
fs.Read(colorType, 1);
fs.Free;
Result := colorType and (1 shl 2) <> 0;
end;
所以它被存储在第26个字节(或0x19作为十六进制),在第3位。
但是,为了简单起见,该函数不检查有效的文件结构。所以它应该在PNG图像被加载到TBitmap之后使用,然后它的布尔值支持透明度可以存储,例如在TImage的Tag
属性中(或任何你想要的地方)。