Как да копирате растерна графика в масив от байтове

Как да копирате растерна графика за масив от байтове?

Желателно използване ход функция (това беше по-бързо), а след това savetostream много бавно. Това е в общи линии всичко.

Работа с и чрез пикселите може bitmap.canvas.pixels [X, Y], а по-скоро чрез scanline.







GetDiBits
GetBitmapBits (стар, но работи)

bitmap.canvas.pixels [X, Y] - той работи по-бавно от savetostream.
а как да използвате scanline и ход на процедурата за (палачинка въпросната пише функция) копие от BMP в масива. Например аз дори не на първия ред не е копирано (кода по-долу не се опитва да копирате целия BMP в масив, показано тук, че дори и на първия ред не се копира в масива):

процедура TForm1.Button1Click (Sender: TObject);
Var б: tbitmap;
И, Й: цяло число;
р: pbytearray;
ите: низ;
аа: масив [0..1024 * 4] на байт;
започвам
б: = TBitmap.Create;
b.LoadFromFile ( "F: \ file.bmp");
защото: = 0 до b.Height-1 направи започва
р: = b.ScanLine [Ь];
ход (аа, стр ^, b.Width);
приключи;
приключи;

Аз не съм толкова правя? е третият параметър е неправилна процедура ход?

в кода по-долу, аз попълнено TBitmapInfo структура, но наистина не разбирам, че заместникът на getdibits функция в първия параметър, и вместо масив. Някои източници вместо DC, предава "getdc (0)", за да "bmp.canvas.handle". И каква трябва да бъде масив?

процедура TForm1.Button3Click (Sender: TObject);
Var
BitInfo1: TBitmapInfo;
б: tbitmap;
DC1: HDC;
аа: масив [0..80000] на байт;
ите: низ;
започвам
б: = tbitmap.Create;
b.LoadFromFile ( "F: \ file.bmp");
ZeroMemory (@ BitInfo1, sizeOf (BitInfo1));
с bitinfo1.bmiHeader правя
започвам
biSize: = SizeOf (TBITMAPINFOHEADER);
biWidth: = B.Width;
biHeight: = B.Height;
биплани: = 1;
biBitCount: = 32;
biCompression: = 0;
biSizeimage: = 0;
biXPelsPerMeter: = 1;
biYPelsPerMeter: = 1;
biClrUsed: = 0;
biClrImportant: = 0;
приключи;
GetDIBits (b.Canvas.Handle, b.Handle, 0, 0, @aa, BitInfo1, DIB_RGB_COLORS);
приключи;

Тук правя грешно?


процедура TForm1.Button1Click (Sender: TObject);
Var б: tbitmap;
И, Й: цяло число;
р: pbytearray;
ите: низ;
аа: масив [0..1024 * 4] на байт;
започвам
б: = TBitmap.Create;
b.LoadFromFile ( "F: \ file.bmp");
защото: = 0 до b.Height-1 направи започва
р: = b.ScanLine [Ь];
ход (аа, стр ^, b.Width);
приключи;
приключи;

В този код, ще трябва да се определи и b.pixelFormat b.Width и b.Height







Не, аз съм объркан посока. Харесва ми и така трябва да работи.

тип
TRGBQArray = масив от TRGBQuad;
Var


FWidth: = Value.Width;
FHeight: = Value.Height;
SetLength (FA, FHeight * FWidth);
с FInfo.bmiHeader направя започне
biWidth: = FWidth;
biHeight: = FHeight;
biSize: = SizeOf (TBITMAPINFOHEADER);
biCompression: = BI_RGB;
biBitCount: = 32;
биплани: = 1;
biSizeImage: = 0; // ((biWidth * biBitCount + 31) Разделения 32) * biHeight * 4;
приключи;
GetDIBits (Value.Canvas.Handle, Value.Handle, 0, FHeight, FA, FInfo, DIB_RGB_COLORS);

2 JEL
По същия начин, палачинка със смесена източник Цел :) (I)
2 Alxx
b.Width и b.Height и b.pixelFormat вече са определени, веднага след зареждането на растерна графика "и

2 MBO
изкуството, създадени тук е кода на шаблона:

процедура TForm1.Button4Click (Sender: TObject);
тип
TRGBQArray = масив от TRGBQuad;
Var
ФА: TRGBQArray;
FInfo: tbitmapinfo;
Стойност: TBitmap;
започвам
стойност: = tbitmap.Create;
value.LoadFromFile ( "г: \ kofe1.bmp");
SetLength (FA, value.Height * value.Width);
с FInfo.bmiHeader направя започне
biWidth: = value.Width;
biHeight: = value.Height;
biSize: = SizeOf (TBITMAPINFOHEADER);
biCompression: = BI_RGB;
biBitCount: = 24;
биплани: = 1;
biSizeImage: = ((value.Width * 24 + 31) Разделения 32) * value.Height * 4; // 0
приключи;
GetDIBits (value.Canvas.Handle, Value.Handle, 0, value.Height, FA, FInfo, DIB_RGB_COLORS);
приключи;

Може да съм грешен biSizeImage, но тя не работи. т.е. когато е налице:
(FA, value.Height * value.Width);
ясно е, че на мястото е бил разпределен в масива, но след GetDIBits празна. Трябва да съм ясно са се объркали.

biSizeImage трябва да бъде от 0 до 24 и 32-битови изображения

Странно, но заменя biSizeImage 0, но все пак показва, че наблюдаваните теми празна :(

код на работна например. Сигурен съм, че един и същ PixelFormat?

Сега за надеждността на малко променени:

Ето един пример на статичен масив


процедура TForm1.Button2Click (Sender: TObject);
Var Ь: tbitmap;
а: масив [0..9,0..9] на TRGBQuad;
ите: низ;
информация: tbitmapinfo;
И, Й: цяло число;
започвам
б: = tbitmap.create;
b.PixelFormat: = pf24bit;
b.width: = 10;
b.height: = 10;
b.Canvas.moveTo (0,0);
b.Canvas.LineTo (6,6);
с info.bmiHeader направя започне
biWidth: = b.Width;
biHeight: = b.Height;
biSize: = SizeOf (TBITMAPINFOHEADER);
biCompression: = BI_RGB;
biBitCount: = 32;
биплани: = 1;
biSizeImage: = 0;
приключи;
GetDIBits (b.canvas.handle, B.Handle, 0, B.Height, @ а, информация, DIB_RGB_COLORS);
защото: = 0 до 9 започвайте
S: = "";
за к: = 0 до 9 направи S: = S + inttohex (а [Ь, й] .rgbRed, 2) + "";
memo1.lines.add (и);
приключи;
image1.picture.assign (б);
b.free;
приключи;

Благодаря ви много!
С стат. масив работи.

и динамични произведения.
Лечение Опция -
GetDIBits (value.Canvas.Handle, Value.Handle, 0, value.Height, @ FA [0], FInfo, DIB_RGB_COLORS);

Да, наистина. Благодаря отново.

Интересното е, - bmp.savetostream, по-бързо запълва масив от байтове, от:

по-долу, лъвския дял от време отнема scanline функция, това може да бъде izbzhat ако juzat Библията. G32, но не може да се инсталира pixelformat :(

а: масив [0..1023] на байт;
б: масив [0..1023 * 768]

за к: = 0-1023 започвайте
р: = b.scanline [й];
ход (р ^, а [0], 1024);
защото: = к * 1024 до i1 * 1024 + 1023 направи // добавят всички
б [Ь]: = на [I-J * 1024]; // в оригиналния масив
приключи;


GetDIBits (bmp.Canvas.Handle, bmp.Handle, 0, bmp.Height, @ FA [0] [0], FInfo, DIB_RGB_COLORS); // FA, DIN. или изделия. масивът не е от значение