1

我正在将 PNG 图像加载到FMX.Type.TBitmapDelphi-XE2 Update3 FireMonkey HD 应用程序中。如何检查加载的 PNG 图像是否具有 alpha 通道?

目前,如果我加载带有 alpha 通道的图像,它会Bitmap.Scanline[Y]^[X]以 $AABBGGRR 的形式包含 alpha 信息。但是,如果我加载没有 alpha 的 PNG 图像,则所述记录只有 $00BBGGRR 条目(AA = 0),就像具有清晰 alpha 的图像一样。因此出现了问题 - 如何确定它是具有 alpha 完全透明的 RGBA 图像还是 RGB 图像(在这种情况下,我将对其进行处理以使 alpha 完全不透明)。注意:检查所有像素不是一种选择。

FMX TBitmap 没有PixelFormat属性,我也找不到HasAlpha标志。

4

2 回答 2

2

你可能不会喜欢这个。

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;
于 2012-01-02T22:53:47.370 回答
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之后使用,然后可以将其用于透明度支持的布尔值存储在例如TagTImage的属性中(或任何你想要的地方)。

于 2017-09-21T22:56:03.193 回答