В Delphi 12 Athens появилась возможность работы с графикой через библиотеку SKIA. Однако, как показывает практика, при использовании SKIA для прямой конвертации TBitmap в lossless WebP формат могут возникать проблемы. В частности, сгенерированное изображение может оказаться поврежденным, отображаться некорректно или содержать артефакты, связанные с альфа-каналом.
Описание проблемы:
Пользователь столкнулся с проблемой при попытке сохранить TBitmap (32-битный, содержащий 2D графику) в lossless WebP формат с использованием SKIA. Изображение, полученное в результате, оказалось поврежденным и не отображалось корректно в графических редакторах.
Код, вызывающий проблему:
uses
System.Skia, Vcl.Skia;
procedure SaveAsWebP(aBitmap: TBitmap; aOutputfilename: string; Compressionfactor: integer; out MimeContentType: string);
begin
var skimage := aBitmap.ToSKImage;
skimage.encodetofile(aOutputfilename, TSkEncodedImageFormat.WebP, Compressionfactor);
MimeContentType := 'image/webp';
end;
Анализ проблемы:
Предположительно, проблема связана с некорректной обработкой альфа-канала при прямой конвертации TBitmap в TSkImage с последующим сохранением в WebP. WebP (особенно VP8L, используемый для lossless сжатия) имеет определенные ограничения в работе с альфа-каналом и цветовыми пространствами.
В коде создания TBitmap явно указано ResultBitmap.Alphaformat := TAlphaFormat.afIgnored; и функция TSkBitmapHelper.ToSkImage (из Vcl.Skia) обрабатывает этот случай, устанавливая LAlphaType := TSkAlphaType.Opaque;. Тем не менее, проблема сохраняется.
Решение (Workaround):
В качестве обходного решения предложено сохранять TBitmap во временный поток памяти, а затем создавать TSkImage из этого потока.
Использование TBitmap.SaveToStream и TSkImage.MakeFromEncodedStream позволяет SKIA более корректно интерпретировать данные изображения, возможно, выполняя необходимые преобразования цветового пространства и альфа-канала перед кодированием в WebP. Этот метод, по-видимому, обходит ошибку, возникающую при прямой конвертации.
Альтернативные решения и рекомендации:
Явная обработка альфа-канала: Перед конвертацией в WebP убедитесь, что альфа-канал обработан корректно. Если изображение не должно содержать прозрачности, можно явно установить все значения альфа-канала в 255 (полностью непрозрачный). Это можно сделать, перебирая пиксели TBitmap и устанавливая значение альфа-канала.
procedure MakeBitmapOpaque(Bitmap: TBitmap);
var X, Y: Integer;
Color: TColor;
begin
for Y := 0 to Bitmap.Height - 1 do
begin
for X := 0 to Bitmap.Width - 1 do
begin
Color := Bitmap.Canvas.Pixels[X, Y];
Bitmap.Canvas.Pixels[X, Y] := RGB(GetRValue(Color), GetGValue(Color), GetBValue(Color)); // Альфа-канал автоматически станет 255
end;
end;
end;
Использование сторонних библиотек: Рассмотрите возможность использования сторонних библиотек для работы с WebP, которые могут более надежно обрабатывать различные форматы изображений и альфа-канал. В Delphi существует несколько библиотек для работы с WebP, например, libwebp wrapper.
Проверка настроек кодирования WebP: Убедитесь, что настройки кодирования WebP соответствуют вашим требованиям. Возможно, изменение параметров кодирования (например, уровня сжатия, использования lossless или lossy режима) может повлиять на результат.
Сообщение об ошибке: Сообщите об обнаруженной проблеме разработчикам Delphi (Embarcadero). Это поможет им исправить ошибку в будущих версиях продукта.
Вывод:
Проблема с генерацией lossless WebP изображений в Delphi 12 с использованием SKIA, по-видимому, связана с некорректной обработкой альфа-канала при прямой конвертации TBitmap в TSkImage. Предложенный workaround с использованием потока памяти позволяет обойти эту проблему. В качестве альтернативных решений рекомендуется явная обработка альфа-канала, использование сторонних библиотек и проверка настроек кодирования WebP. Также важно сообщить об ошибке разработчикам Delphi.
В Delphi 12 при прямой конвертации TBitmap в lossless WebP через SKIA возникает проблема с альфа-каналом, приводящая к повреждению изображения, для решения которой предложен обходной путь с использованием потока памяти.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.