Как создать Bitmap из массива пикселей

Previous  Top  Next

    
 

 

Один из способов создания битмапа из массива пикселей заключается в использовании Windows API функции CreateDiBitmap(). Это позволит использовать один из многих форматов битмапа, которые Windows использует для хранения пикселей. Следующий пример создаёт 256-цветный битмап из массива пикселей. Битмап состит из 256 оттенков серого цвета плавно переходящих от белого к чёрному. Обратите внимание, что Windows резервирует первые и последние 10 цветов для системных нужд, поэтому Вы можете получить максимум 236 оттенков серого.

 

Code:

{$IFNDEF WIN32}

type

{Used for pointer math under Win16}

PPtrRec = ^TPtrRec;

TPtrRec = record

   Lo : Word;

   Hi : Word;

end;

{$ENDIF}

 

{Used for huge pointer math}

function GetBigPointer(lp : pointer;

                      Offset : Longint) : Pointer;

begin

{$IFDEF WIN32}

GetBigPointer := @PByteArray(lp)^[Offset];

{$ELSE}

Offset := Offset + TPtrRec(lp).Lo;

GetBigPointer := Ptr(TPtrRec(lp).Hi + TPtrRec(Offset).Hi *

                      SelectorInc,

                      TPtrRec(Offset).Lo);

{$ENDIF}

end;

 

procedure TForm1.Button1Click(Sender: TObject);

var

hPixelBuffer : THandle; {Handle to the pixel buffer}

lpPixelBuffer : pointer; {pointer to the pixel buffer}

lpPalBuffer : PLogPalette; {The palette buffer}

lpBitmapInfo : PBitmapInfo; {The bitmap info header}

BitmapInfoSize : longint; {Size of the bitmap info header}

BitmapSize : longint; {Size of the pixel array}

PaletteSize : integer; {Size of the palette buffer}

i : longint; {loop variable}

j : longint; {loop variable}

OldPal : hPalette; {temp palette}

hPal : hPalette; {handle to our palette}

hBm : hBitmap; {handle to our bitmap}

Bm : TBitmap; {temporary TBitmap}

Dc : hdc; {used to convert the DOB to a DDB}

IsPaletteDevice : bool;

begin

Application.ProcessMessages;

{If range checking is on - turn it off for now}

{we will remember if range checking was on by defining}

{a define called CKRANGE if range checking is on.}

{We do this to access array members past the arrays}

{defined index range without causing a range check}

{error at runtime. To satisfy the compiler, we must}

{also access the indexes with a variable. ie: if we}

{have an array defined as a: array[0..0] of byte,}

{and an integer i, we can now access a[3] by setting}

{i := 3; and then accessing a[i] without error}

{$IFOPT R+}

{$DEFINE CKRANGE}

{$R-}

{$ENDIF}

 

{Lets check to see if this is a palette device - if so, then}

{we must do palette handling for a successful operation.}

{Get the screen's dc to use since memory dc's are not reliable}

dc := GetDc(0);

IsPaletteDevice :=

   GetDeviceCaps(dc, RASTERCAPS) and RC_PALETTE = RC_PALETTE;

{Give back the screen dc}

dc := ReleaseDc(0, dc);

 

{Размер информации о рисунке должен равняться размеру BitmapInfo}

{плюс размер таблицы цветов, минус одна таблица}

{так как она уже объявлена в TBitmapInfo}

BitmapInfoSize := sizeof(TBitmapInfo) + (sizeof(TRGBQUAD) * 255);

 

{The bitmap size must be the width of the bitmap rounded}

{up to the nearest 32 bit boundary}

BitmapSize := (sizeof(byte) * 256) * 256;

 

{Размер палитры должен равняться размеру TLogPalette}

{плюс количество ячеек цветовой палитры - 1, так как}

{одна палитра уже объявлена в TLogPalette}

if IsPaletteDevice then

  PaletteSize := sizeof(TLogPalette) + (sizeof(TPaletteEntry) * 255);

 

{Выделяем память под BitmapInfo, PixelBuffer, и Palette}

GetMem(lpBitmapInfo, BitmapInfoSize);

hPixelBuffer := GlobalAlloc(GHND, BitmapSize);

lpPixelBuffer := GlobalLock(hPixelBuffer);

 

if IsPaletteDevice then

   GetMem(lpPalBuffer, PaletteSize);

 

{Заполняем нулями BitmapInfo, PixelBuffer, и Palette}

FillChar(lpBitmapInfo^, BitmapInfoSize, #0);

FillChar(lpPixelBuffer^, BitmapSize, #0);

if IsPaletteDevice then

   FillChar(lpPalBuffer^,PaletteSize, #0);

 

{Заполняем структуру BitmapInfo}

lpBitmapInfo^.bmiHeader.biSize := sizeof(TBitmapInfoHeader);

lpBitmapInfo^.bmiHeader.biWidth := 256;

lpBitmapInfo^.bmiHeader.biHeight := 256;

lpBitmapInfo^.bmiHeader.biPlanes := 1;

lpBitmapInfo^.bmiHeader.biBitCount := 8;

lpBitmapInfo^.bmiHeader.biCompression := BI_RGB;

lpBitmapInfo^.bmiHeader.biSizeImage := BitmapSize;

lpBitmapInfo^.bmiHeader.biXPelsPerMeter := 0;

lpBitmapInfo^.bmiHeader.biYPelsPerMeter := 0;

lpBitmapInfo^.bmiHeader.biClrUsed := 256;

lpBitmapInfo^.bmiHeader.biClrImportant := 256;

 

{Заполняем таблицу цветов BitmapInfo оттенками серого: от чёрного до белого}

for i := 0 to 255 do begin

   lpBitmapInfo^.bmiColors[i].rgbRed := i;

   lpBitmapInfo^.bmiColors[i].rgbGreen := i;

   lpBitmapInfo^.bmiColors[i].rgbBlue := i;

end;

 

 

©Drkb::03764

Взято из http://forum.sources.ru