В статье будет рассмотрена проблема, связанная с сохранением изображений в формате PNG с прозрачными слоями при использовании компонента ImgView32 в среде разработки Delphi. Проблема заключается в том, что несмотря на попытки установить прозрачность для определенных участков изображения, после сохранения файл имеет белый фон.
Пример кода инициализации ImgView32 и создания слоя
procedure TForm.Create(Sender: TObject);
var
P: TPoint;
W, H: Single;
imwidth, imheight: Integer;
begin
// Инициализация параметров изображения
imwidth := Iv1.Width;
imheight := Iv1.Height;
with Iv1 do
begin
Selection := nil;
Layers.Clear; // Очистка слоев
Scale := 1;
Scaled := True;
Bitmap.DrawMode := dmTransparent; // Установка режима прозрачности
Bitmap.SetSize(imwidth, imheight);
Bitmap.Canvas.Pen.Width := 4; // Ширина пера для рисования
end;
BL := TBitmapLayer.Create(Iv1.Layers); // Создание нового слоя
try
with BL do
begin
Bitmap.DrawMode := dmTransparent;
Bitmap.SetSize(imwidth, imheight);
Bitmap.Canvas.Pen.Width := penWidth; // Ширина пера для данного слоя
Bitmap.Canvas.Pen.Color := penColor; // Цвет пера
Location := GR32.FloatRect(0, 0, imwidth, imheight);
Scaled := False; // Отключение масштабирования слоя
end;
except
BL.Free;
raise;
end;
end;
Пример кода рисования на слое
procedure TForm.DrawLine;
var
bm32: TBitmapLayer;
begin
// Получение ссылки на слой для рисования
bm32 := Iv1.Layers[0] as TBitmapLayer;
with bm32.Canvas do
begin
Pen.Color := clWhite; // Цвет пера - белый
Brush.Color := clWhite;
Rectangle(0, 0, bm32.Width-1, bm32.Height-1); // Заливка слоя цветом пера
Pen.Color := WinColor(ColorPickerGTK1.SelectedColor);
Brush.Color := clWhite; // Возможно, стоит использовать другой цвет для кисти
Pen.Width := 4;
MoveTo(0, bm32.Height);
LineTo(bm32.Width, bm32.Height-50); // Рисуем линию на слое
end;
end;
Проблема сохранения изображения в формате PNG с прозрачностью
При попытке сохранить изображение с использованием следующего кода:
procedure TForm.SaveButtonClick(Sender: TObject);
var
myLay: TBitmapLayer;
begin
myLay := Iv1.Layers.Items[0] as TBitmapLayer; // Получаем ссылку на слой для сохранения
SavePNGTransparentX(myLay.Bitmap); // Вызов функции сохранения с прозрачностью
end;
procedure TForm.SavePNGTransparentX(bm32: TBitmap32);
var
Y, X: Integer;
Png: TPortableNetworkGraphic32;
begin
bm32.ResetAlpha; // Сброс альфа-канала для корректного определения прозрачных участков
for Y := 0 to bm32.Height-1 do
for X := 0 to bm32.Width-1 do
if IsWhite(bm32.Pixel[X, Y]) then // Проверка на белый цвет
bm32.Pixel[X,Y]:=Color32(255,255,255,0); // Установка цвета в полностью прозрачный
Png := TPortableNetworkGraphic32.Create;
try
Png.Assign(bm32);
Png.SaveToFile('C:\Path\To\TransparentImage.png');
finally
Png.Free;
end;
end;
function TForm.IsWhite(Color32: TColor32): Boolean;
begin
Result := (TColor32Entry(Color32).B = 255) and
(TColor32Entry(Color32).G = 255) and
(TColor32Entry(Color32).R = 255);
end;
Изображение сохраняется с белым фоном вместо прозрачного, как ожидалось.
Решение проблемы
Для решения проблемы была предложена следующая стратегия:
Изменить анализ битной глубины и создание палитры в классе TPortableNetworkGraphic32 путем изменения значения свойства IsPalette на False.
Исправить функцию обнаружения прозрачных пикселей, изменив проверку с белого цвета на черный.
Вот исправленный код функции сохранения изображения:
procedure TForm.SavePNGTransparentX(bm32: TBitmap32);
var
Y, X: Integer;
Png: TPortableNetworkGraphic32;
begin
bm32.ResetAlpha;
for Y := 0 to bm32.Height-1 do
for X := 0 to bm32.Width-1 do
if IsBlack(bm32.Pixel[X, Y]) then // Проверка на черный цвет
bm32.Pixel[X,Y]:=Color32(0, 0, 0, 0); // Установка цвета в полностью прозрачный
Png := TPortableNetworkGraphic32.Create;
try
Png.Assign(bm32);
Png.SaveToFile('C:\Path\To\TransparentImage.png');
finally
Png.Free;
end;
end;
function TForm.IsBlack(Color32: TColor32): Boolean;
begin
Result := (TColor32Entry(Color32).B = 0) and
(TColor32Entry(Color32).G = 0) and
(TColor32Entry(Color32).R = 0);
end;
Также, для полного решения проблемы, нужно внести изменения в исходный код компонента GR32_PNG, изменив логику определения битной глубины и типа цвета.
Заключение
В данном ответе были рассмотрены основные шаги по решению проблемы сохранения прозрачных слоев изображения в формате PNG при использовании ImgView32 в Delphi. Описаны примеры кода, которые помогут разработчикам избежать ошибок связанных с неправильной настройкой альфа-канала и обеспечить корректное отображение прозрачности в итоговом изображении.
Проблема связана со сохранением изображений в формате PNG с прозрачными слоями при использовании компонента ImgView32 в среде Delphi, где после установки прозрачности определенные участки изображения сохраняются с белым фоном вместо ожидаемой прозрачност
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.