Разработчики, работающие с графикой в среде Delphi, часто сталкиваются с необходимостью обработки альфа-каналов изображений. В частности, при работе с библиотекой FireMonkey в версии Delphi XE2 Update3 может возникнуть потребность проверить, содержит ли загруженное PNG изображение альфа-канал. Это важно для корректной обработки изображений, например, для изменения прозрачности.
Проблема
При загрузке PNG изображений в FMX.Type.TBitmap в приложении FireMonkey HD не всегда очевидно, содержит ли изображение альфа-канал. В частности, сканлиния (Bitmap.Scanline[Y]^[X]) может содержать информацию об альфа-канале в виде $AABBGGRR, если он присутствует, или $00BBGGRR (где AA = 0), если альфа-канал отсутствует. Однако, поскольку альфа-канал может быть полностью прозрачным, необходимо дополнительная проверка для определения типа изображения (RGBA с прозрачным альфа-каналом или RGB без альфа-канала).
Решение
FMX TBitmap не имеет свойства PixelFormat или флага HasAlpha, поэтому прямой проверки альфа-канала не существует. Однако, в "Подтвержденном ответе" предлагается функция IsAlpha, которая перебирает все пиксели изображения и проверяет, используется ли альфа-канал:
function TBitmap.IsAlpha(const Bitmap: TBitmap): Boolean;
var
I, j: Integer;
Bits: PAlphaColorRecArray;
begin
Bits := PAlphaColorRecArray(Bitmap.StartScanLine);
for j := 0 to Bitmap.Height - 1 do
for I := 0 to Bitmap.Width - 1 do
begin
if Bits[I + (j * Bitmap.Width)].A <> 255 then
begin
Result := True;
Exit;
end;
end;
Result := False;
end;
Альтернативный подход
Альтернативный способ заключается в проверке заголовка PNG файла. Функция PngHasAlphaLayer читает 26-байт из файла, который содержит информацию о типе цвета, включая наличие альфа-канала:
function PngHasAlphaLayer(const f: String): Boolean;
var
fs: TFileStream;
colorType: Byte;
begin
fs := TFileStream.Create(f, fmOpenRead);
try
fs.Position := 25;
fs.Read(colorType, 1);
Result := (colorType and $04) <> 0;
finally
fs.Free;
end;
end;
Этот метод не проверяет валидность структуры файла, но позволяет быстро определить наличие альфа-канала по заголовку файла.
Заключение
Оба подхода имеют свои недостатки: первый требует перебора всех пикселей, что может быть неэффективно, второй предполагает работу с файловой системой, что может быть неудобно в некоторых сценариях. Надеемся, что в будущих обновлениях Embarcadero будут исправлены эти недостатки и предоставлены более удобные инструменты для работы с альфа-каналами в FireMonkey.
Разработчики в Delphi XE2 с использованием FireMonkey сталкиваются с необходимостью проверки наличия альфа-канала в PNG изображениях для корректной обработки прозрачности.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS