Преобразование изображений между форматами TBitmap и TPngImage в проектах с использованием FMX и VCL
При работе с графическими элементами в Delphi, разработчики часто сталкиваются с необходимостью преобразования изображений из одного формата в другой. Особенно это актуально, когда в проекте используются как FMX (FireMonkey), так и VCL (Visual Component Library) формы. В данной статье мы рассмотрим, как можно преобразовать FMX.Graphics.TBitmap в VCL.Graphics.TBitmap или Vcl.Imaging.PngImage.TPngImage.
Проблема
Разработчики, работающие с проектами, содержащими как FMX, так и VCL формы, иногда сталкиваются с необходимостью преобразования битмапов из одного контекста в другой. Это может быть связано с различными задачами, например, при использовании VCL компонентов для обработки изображений или при сохранении изображений в формате PNG.
Решение
Для решения этой задачи можно использовать несколько подходов. Один из них заключается в сохранении изображения в память потока, а затем загрузке его в нужный формат. Однако более эффективный способ заключается в использовании метода Map, который позволяет получить данные битмапа, и затем заполнить новый VCL битмап, используя эти данные.
Подтвержденный ответ
Благодаря помощи Дэвида Хеффернана и некоторым исследованиям, были разработаны функции для преобразования FMX.Graphics.TBitmap в VCL.Graphics.TBitmap. Ниже приведены примеры таких функций.
Первая функция не поддерживает альфа-канал:
function ConvertFmxBitmapToVclBitmap(const b: FMX.Graphics.TBitmap): Vcl.Graphics.TBitmap;
var
data: FMX.Graphics.TBitmapData;
i, j: Integer;
AlphaColor: TAlphaColor;
begin
Result := Vcl.Graphics.TBitmap.Create;
Result.SetSize(b.Width, b.Height);
if b.Map(TMapAccess.Readwrite, data) then
try
for i := 0 to data.Height - 1 do
for j := 0 to data.Width - 1 do
begin
AlphaColor := data.GetPixel(j, i);
Result.Canvas.Pixels[i, j] :=
RGB(
TAlphaColorRec(AlphaColor).R,
TAlphaColorRec(AlphaColor).G,
TAlphaColorRec(AlphaColor).B);
end;
finally
b.Unmap(data);
end;
end;
Вторая функция предназначена для преобразования FMX.Graphics.TBitmap в Vcl.Imaging.PngImage.TPngImage и поддерживает альфа-канал:
function ConvertFmxBitmapToPng(const b: FMX.Graphics.TBitmap): Vcl.Imaging.PngImage.TPngImage;
var
data: FMX.Graphics.TBitmapData;
i, j: Integer;
AlphaColor: TAlphaColor;
AlphaLine: Vcl.Imaging.PngImage.pByteArray;
begin
Result := TPngImage.CreateBlank(COLOR_RGBALPHA, 8, b.Width, b.Height);
if b.Map(TMapAccess.Readwrite, data) then
try
for i := 0 to data.Height - 1 do
begin
AlphaLine := Result.AlphaScanline[i];
for j := 0 to data.Width - 1 do
begin
AlphaColor := data.GetPixel(j, i);
AlphaLine^[j] := TAlphaColorRec(AlphaColor).A;
Result.Pixels[j, i] :=
RGB(
TAlphaColorRec(AlphaColor).R,
TAlphaColorRec(AlphaColor).G,
TAlphaColorRec(AlphaColor).B);
end;
end;
finally
b.Unmap(data);
end;
end;
Комментарии
Обратите внимание, что приведенные функции являются крайне неэффективными и представляют собой наивное решение. Для более высокой производительности рекомендуется ознакомиться с источником, приведенным в комментариях к коду.
Альтернативный ответ с корректировкой
Корректировка функции ConvertFmxBitmapToVclBitmap для работы с прямоугольными изображениями:
function ConvertFmxBitmapToVclBitmap(const b: FMX.Graphics.TBitmap): Vcl.Graphics.TBitmap;
var
data: FMX.Graphics.TBitmapData;
i, j: Integer;
AlphaColor: TAlphaColor;
begin
Result := Vcl.Graphics.TBitmap.Create;
Result.SetSize(b.Width, b.Height);
if b.Map(TMapAccess.Readwrite, data) then
try
for i := 0 to data.Height - 1 do
for j := 0 to data.Width - 1 do
begin
AlphaColor := data.GetPixel(i, j); // Исправлено направление индексации
Result.Canvas.Pixels[i, j] :=
RGB(
TAlphaColorRec(AlphaColor).R,
TAlphaColorRec(AlphaColor).G,
TAlphaColorRec(AlphaColor).B);
end;
finally
b.Unmap(data);
end;
end;
Заключение
В данной статье мы рассмотрели методы преобразования битмапов между FMX и VCL контекстами. Представленные функции могут служить отправной точкой для дальнейшей разработки и оптимизации процесса преобразования изображений в проектах, использующих разные библиотеки Delphi.
Разработчики используют Delphi и сталкиваются с задачей преобразования изображений из формата TBitmap FMX в TBitmap или TPngImage VCL для совместимости в проектах, использующих обе библиотеки.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS