Как исправить искажение цветов при использовании свойства TBitmap.Palette в Delphi
При работе с изображениями в среде разработки Delphi часто возникают вопросы, связанные с корректной обработкой цветов. Один из таких вопросов касается искажения цветов при использовании свойства TBitmap.Palette. Данное свойство позволяет получить палитру цветов для 8-битного изображения, но его некорректное использование может привести к неожиданным результатам, как в случае с пользователем, который столкнулся с проблемой "Wrong colors extracted from TBitmap.Palette".
Описание проблемы
Пользователь пытается извлечь цвета из 8-битного изображения с использованием свойства TBitmap.Palette, но при этом цвета искажаются. Для визуального сравнения результатов был создан простой тест, который демонстрирует проблему. Код, используемый для извлечения цветов, представлен ниже:
procedure TForm36.FormCreate(Sender: TObject);
var
LBitmap1, LBitmap2: TBitmap;
LPaletteEntries: TMaxLogPalette;
P1: PByteArray;
P2: PRGBTriple;
X,Y: Integer;
begin
{$POINTERMATH ON}
LBitmap1 := TBitmap.Create;
LBitmap1.LoadFromFile('E:\3x2x8.bmp');
img1.Picture.Assign(LBitmap1);
LBitmap2 := TBitmap.Create;
LBitmap2.Width := LBitmap1.Width;
LBitmap2.Height := LBitmap1.Height;
LBitmap2.PixelFormat := pf24bit;
GetPaletteEntries(LBitmap1.Palette, 0, 256, LPaletteEntries);
for Y := 0 to LBitmap1.Height - 1 do
begin
P1 := LBitmap1.ScanLine[Y];
P2 := LBitmap2.ScanLine[Y];
for X := 0 to LBitmap1.Width - 1 do
begin
P2[X].rgbtBlue := LPaletteEntries.palPalEntry[P1[X]].peBlue;
P2[X].rgbtGreen := LPaletteEntries.palPalEntry[P1[X]].peGreen;
P2[X].rgbtRed := LPaletteEntries.palPalEntry[P1[X]].peRed;
end;
end;
img2.Picture.Assign(LBitmap2);
end;
Подтвержденный ответ
Проблема заключается в том, что пользователь неправильно использует функцию GetPaletteEntries. Вместо того чтобы передать в функцию структуру palPalEntry: array [0..255] of TPaletteEntry;, он использует структуру TMaxLogPalette, что приводит к искажению цветов.
Шаги по исправлению ошибки
Инициализируйте массив TPaletteEntry для хранения палитры цветов:
var
PaletteEntries: array [0..255] of TPaletteEntry;
Вызовите функцию GetPaletteEntries, передав в нее корректный массив PaletteEntries:
Используйте значения из массива PaletteEntries для установки цветов пикселей в новом изображении:
for X := 0 to LBitmap1.Width - 1 do
begin
P2[X].rgbtBlue := PaletteEntries[P1[X]].peBlue;
P2[X].rgbtGreen := PaletteEntries[P1[X]].peGreen;
P2[X].rgbtRed := PaletteEntries[P1[X]].peRed;
end;
Альтернативные замечания
Используйте формат PNG для не фотографических изображений, так как JPEG может вносить артефакты, которые могут сбивать с толку при анализе пикселей и их цветов.
Всегда проверяйте типы данных, используемые в функциях, и убедитесь, что они соответствуют ожидаемым параметрам.
Заключение
При работе с изображениями в Delphi важно обращать внимание на детали, такие как корректное использование функций и структур. Исправление ошибки в вызове GetPaletteEntries позволит избежать искажения цветов при использовании свойства TBitmap.Palette.
Пользователь столкнулся с проблемой искажения цветов при использовании свойства `TBitmap.Palette` в Delphi из-за неправильного использования функции `GetPaletteEntries`, применяя для этого неподходящую структуру данных.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.