Delphi - объектно-ориентированный язык программирования, разработанный компанией Borland в 1995 году. Он основан на языке программирования Pascal, но имеет более расширенные возможности и добавлены новые функции.
Delphi является интегрированной средой разработки (IDE), которая позволяет разрабатывать программное обеспечение для различных платформ, включая Windows, macOS, Android и iOS. Delphi достигает многоплатформенности с помощью...
Мне необходимо изменить цветовую палитру изображения с помощью SetBitmapBits, но у меня, к сожалению, ничего не получается.
Использование SetBitmapBits - не очень хорошая идея, поскольку она имеет дело с HBitmaps, в котором формат пикселя не определен. Несомненно, это более безопасная операция, но никаких гарантий по ее выполнению дать невозможно.
Взамен я предлагаю использовать функции DIB API. Вот некоторый код, позволяющий вам изменять таблицу цветов. Просто напишите метод с такими же параметрами, как у TFiddleProc и и изменяйте ColorTable, передаваемое как параметр. Затем просто вызовите процедуру FiddleBitmap, передающую TBitmap и ваш fiddle-метод, например так:
FiddleBitmap( MyBitmap, Fiddler ) ;
typeTFiddleProc = procedure
(var
ColorTable: TColorTable) of
object
; const
LogPaletteSize = sizeof(TLogPalette) + sizeof(TPaletteEntry) * 255; function
PaletteFromDIB(BitmapInfo: PBitmapInfo): HPalette; var
LogPalette: PLogPalette; i: integer; Temp: byte; begin
with
BitmapInfo^, bmiHeader do
begin
GetMem(LogPalette, LogPaletteSize); try
with
LogPalette^ do
begin
palVersion := $300; palNumEntries := 256; Move(bmiColors, palPalEntry, sizeof(TRGBQuad) * 256); for
i := 0 to
255 do
with
palPalEntry[i] do
begin
Temp := peBlue; peBlue := peRed; peRed := Temp; peFlags := PC_NOCOLLAPSE; end
; { создаем палитру } Result := CreatePalette(LogPalette^); end
; finally
FreeMem(LogPalette, LogPaletteSize); end
; end
; end
;
{ Следующая процедура на основе изображения создает DIB, изменяет ее таблицу цветов, создавая тем самым новую палитру, после чего передает ее обратно изображению. При этом используется метод косвенного вызова, с помощью которого изменяется палитра цветов - ей передается array[ 0..255 ] of TRGBQuad. } procedureFiddleBitmap(Bitmap: TBitmap; FiddleProc: TFiddleProc); const
BitmapInfoSize = sizeof(TBitmapInfo) + sizeof(TRGBQuad) * 255; var
BitmapInfo: PBitmapInfo; Pixels: pointer; InfoSize: integer; ADC: HDC; OldPalette: HPalette; begin
{ получаем DIB } GetMem(BitmapInfo, BitmapInfoSize); try
{ меняем таблицу цветов - ПРИМЕЧАНИЕ: она использует 256 цветов DIB } FillChar(BitmapInfo^, BitmapInfoSize, 0); with
BitmapInfo^.bmiHeader do
begin
biSize := sizeof(TBitmapInfoHeader); biWidth := Bitmap.Width; biHeight := Bitmap.Height; biPlanes := 1; biBitCount := 8; biCompression := BI_RGB; biClrUsed := 256; biClrImportant := 256; GetDIBSizes(Bitmap.Handle, InfoSize, biSizeImage);
{ распределяем место для пикселей } Pixels := GlobalAllocPtr(GMEM_MOVEABLE, biSizeImage); try{ получаем пиксели DIB } ADC := GetDC(0); try
OldPalette := SelectPalette(ADC, Bitmap.Palette, false
); try
RealizePalette(ADC); GetDIBits(ADC, Bitmap.Handle, 0, biHeight, Pixels, BitmapInfo^, DIB_RGB_COLORS); finally
SelectPalette(ADC, OldPalette, true
); end
; finally
ReleaseDC(0, ADC); end
;
{ теперь изменяем таблицу цветов } FiddleProc(PColorTable(@BitmapInfo^.bmiColors)^); { создаем палитру на основе новой таблицы цветов } Bitmap.Palette := PaletteFromDIB(BitmapInfo); OldPalette := SelectPalette(Bitmap.Canvas.Handle, Bitmap.Palette, false); try
RealizePalette(Bitmap.Canvas.Handle); StretchDIBits(Bitmap.Canvas.Handle, 0, 0, biWidth, biHeight, 0, 0, biWidth, biHeight, Pixels, BitmapInfo^, DIB_RGB_COLORS, SRCCOPY); finally
SelectPalette(Bitmap.Canvas.Handle, OldPalette, true
); end
; finally
GlobalFreePtr(Pixels); end
; end
; finally
FreeMem(BitmapInfo, BitmapInfoSize); end
; end
;
{ Пример "fiddle"-метода } procedureTForm1.Fiddler(var
ColorTable: TColorTable); var
i: integer; begin
for
i := 0 to
255 do
with
ColorTable[i] do
begin
rgbRed := rgbRed * 9 div
10; rgbGreen := rgbGreen * 9 div
10; rgbBlue := rgbBlue * 9 div
10; end
; end
;