简体   繁体   English

如何检查加载到FMX.TBitmap的PNG图像是否有alpha通道?

[英]How to check if the PNG image loaded into FMX.TBitmap has an alpha channel?

I'm loading PNG images into FMX.Type.TBitmap in Delphi-XE2 Update3 FireMonkey HD application. 我加载PNG图像到FMX.Type.TBitmap在德尔福XE2 UPDATE3 FireMonkey HD应用程序。 How do I check if loaded PNG image has an alpha channel or not? 如何检查加载的PNG图像是否具有Alpha通道?

Currently if I load an image with an alpha channel it has alpha info in Bitmap.Scanline[Y]^[X] in a form of $AABBGGRR. 目前,如果我加载带有alpha通道的图像,它在$ AABBGGRR形式的Bitmap.Scanline[Y]^[X]中有alpha信息。 However if I load PNG image without alpha the said record has only $00BBGGRR entries (AA = 0), just like an image with clear alpha. 但是,如果我加载没有alpha的PNG图像,则所述记录只有$ 00BBGGRR条目(AA = 0),就像具有清晰alpha的图像一样。 Hence the problem - how to determine if it is RGBA image with the alpha fully transparent or it is a RGB image (in this case I will process it to make the alpha fully opaque). 因此问题 - 如何确定它是否是具有完全透明的alpha的RGBA图像,或者它是RGB图像(在这种情况下,我将处理它以使alpha完全不透明)。 Note: Checking through all pixels is not an option. 注意:无法检查所有像素。

FMX TBitmap has no PixelFormat property, nor I could find HasAlpha flag. FMX TBitmap没有PixelFormat属性,也没有找到HasAlpha标志。

Following function checks if a PNG file has a transparency channel. 以下功能检查PNG文件是否具有透明通道。 This is easy, since the main PNG header has a fixed length and the data information block IHDR must be the first occurring block. 这很容易,因为主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;

So it is stored in the 26th byte (or 0x19 as hex), in the 3rd bit. 因此它存储在第3个字节中的第26个字节(或0x19为十六进制)中。

However, this function does not check for a valid file structure for simplicity reasons. 但是,出于简化原因,此函数不检查有效的文件结构。 So it should be used after the PNG image has been loaded to TBitmap and then its boolean value for transparency support could be stored eg in the Tag property of TImage (or wherever you want). 所以它应该在PNG图像加载到TBitmap之后使用,然后它的透明支持的布尔值可以存储在例如TImage的Tag属性中(或者你想要的任何地方)。

You're probably not going to like this. 你可能不会喜欢这个。

All bitmaps in FMX are 32-bit, and they are loaded and saved using code from the OS, which is all 32-bit. FMX中的所有位图都是32位,它们使用来自OS的代码加载和保存,这些代码都是32位的。

So, the real answer is that all bitmaps have an alpha channel. 所以,真正的答案是所有位图都有一个alpha通道。

But, what you really want to know is whether the bitmap uses the alpha channel, and the only way to tell this would be to iterate over every pixel and see if any have an alpha channel which is <> 255. 但是,你真正想知道的是位图是否使用了alpha通道,而告诉它的唯一方法就是迭代每个像素并查看是否有任何<> 255的alpha通道。

I would recommmend something like the following (untested): 我会推荐类似以下内容(未经测试):

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM