如何检查加载到 FMX.TBitmap 的 PNG 图像是不是具有 alpha 通道?
Posted
技术标签:
【中文标题】如何检查加载到 FMX.TBitmap 的 PNG 图像是不是具有 alpha 通道?【英文标题】:How to check if the PNG image loaded into FMX.TBitmap has an alpha channel?如何检查加载到 FMX.TBitmap 的 PNG 图像是否具有 alpha 通道? 【发布时间】:2011-12-28 08:26:15 【问题描述】:我在 Delphi-XE2 Update3 FireMonkey HD 应用程序中将 PNG 图像加载到 FMX.Type.TBitmap
。如何检查加载的 PNG 图像是否具有 alpha 通道?
目前,如果我加载带有 alpha 通道的图像,它在 Bitmap.Scanline[Y]^[X]
中以 $AABBGGRR 的形式具有 alpha 信息。但是,如果我加载没有 alpha 的 PNG 图像,则所述记录只有 $00BBGGRR 条目(AA = 0),就像具有清晰 alpha 的图像一样。因此出现了问题 - 如何确定它是具有 alpha 完全透明的 RGBA 图像还是 RGB 图像(在这种情况下,我将对其进行处理以使 alpha 完全不透明)。注意:检查所有像素不是一种选择。
FMX TBitmap 没有PixelFormat
属性,我也找不到HasAlpha
标志。
【问题讨论】:
【参考方案1】:你可能不会喜欢这个。
FMX 中的所有位图都是 32 位的,它们是使用操作系统中的代码加载和保存的,这些代码都是 32 位的。
所以,真正的答案是所有位图都有一个 Alpha 通道。
但是,您真正想知道的是位图是否使用 Alpha 通道,唯一的判断方法是遍历每个像素并查看是否有任何具有 255 的 Alpha 通道。
我会推荐如下内容(未经测试):
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;
【讨论】:
没错,我不喜欢这个解决方案,虽然我不得不使用它,但这正是我想要避免的。因此问题。 希望 Embarcadero 将在以后的更新中解决此问题。同时我将使用这个解决方案。【参考方案2】:以下函数检查 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;
所以它存储在第 3 位的第 26 个字节(或 0x19 作为十六进制)中。
但是,为了简单起见,此函数不会检查有效的文件结构。所以它应该在PNG图像加载到TBitmap之后使用,然后可以存储其用于透明度支持的布尔值e。 G。在 TImage 的 Tag
属性中(或任何你想要的地方)。
【讨论】:
以上是关于如何检查加载到 FMX.TBitmap 的 PNG 图像是不是具有 alpha 通道?的主要内容,如果未能解决你的问题,请参考以下文章
如何将本地 jpeg 或 png 图像文件加载到 iPhone 应用程序中?