Изменение цветовой палитры изображения

Советы » Цвета и Палитра » Изменение цветовой палитры изображения

Мне необходимо изменить цветовую палитру изображения с помощью SetBitmapBits, но у меня, к сожалению, ничего не получается.

Использование SetBitmapBits - не очень хорошая идея, поскольку она имеет дело с HBitmaps, в котором формат пикселя не определен. Несомненно, это более безопасная операция, но никаких гарантий по ее выполнению дать невозможно.

Взамен я предлагаю использовать функции DIB API. Вот некоторый код, позволяющий вам изменять таблицу цветов. Просто напишите метод с такими же параметрами, как у TFiddleProc и и изменяйте ColorTable, передаваемое как параметр. Затем просто вызовите процедуру FiddleBitmap, передающую TBitmap и ваш fiddle-метод, например так:

FiddleBitmap( MyBitmap, Fiddler ) ;
type

TFiddleProc = 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. } procedure

FiddleBitmap(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"-метода } procedure

TForm1.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

;

Другое по теме:

Категории

Статьи

Советы

Copyright © 2022 - All Rights Reserved - www.delphirus.com