Как проверить, есть ли у PNG-изображения, загруженного в FMX.TBitmap, есть альфа-канал? - PullRequest
1 голос
/ 28 декабря 2011

Я загружаю изображения PNG в FMX.Type.TBitmap в приложении Delphi-XE2 Update3 FireMonkey HD.Как проверить, имеет ли загруженное изображение PNG альфа-канал или нет?

В настоящее время, если я загружаю изображение с альфа-каналом, оно имеет альфа-информацию в Bitmap.Scanline[Y]^[X] в форме $ AABBGGRR.Однако, если я загружаю PNG-изображение без альфа-канала, упомянутая запись содержит только записи $ 00BBGGRR (AA = 0), как и изображение с четким альфа-каналом.Отсюда проблема - как определить, является ли это изображение RGBA с полностью прозрачным альфа-изображением или это изображение RGB (в этом случае я обработаю его, чтобы сделать альфа-изображение полностью непрозрачным).Примечание. Проверка всех пикселей невозможна.

У FMX TBitmap нет свойства PixelFormat, и я не могу найти флаг HasAlpha.

Ответы [ 2 ]

2 голосов
/ 22 сентября 2017

Следующая функция проверяет, есть ли у 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, а затем сохранить его логическое значение для поддержки прозрачности e. г. в свойстве Tag TImage (или где вы хотите).

2 голосов
/ 03 января 2012

Вероятно, вам это не понравится.

Все растровые изображения в FMX являются 32-разрядными, и они загружаются и сохраняются с использованием кода из ОС, которая является 32-разрядной.

Таким образом, реальный ответ заключается в том, что все растровые изображения имеют альфа-канал.

Но, что вы действительно хотите знать, так это то, использует ли растровое изображение альфа-канал, и единственный способ сказать, что этопереберите каждый пиксель и посмотрите, есть ли у него альфа-канал <> 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;
...