Hogyan másolni egy bitmap egy byte tömböt

Hogyan másolni egy bitmap, hogy egy byte tömböt?

Kívánatos használatával áthelyezési funkció (amely gyorsabb volt), egy savetostream majd nagyon lassú. Ez gyakorlatilag minden.

Dolgozni, és át a pixelek bitmap.canvas.pixels [x, y], hanem inkább a scanline.

GetDiBits
GetBitmapBits (régi, de működik)

bitmap.canvas.pixels [x, y] - ez sokkal lassabban fut, mint savetostream.
hogyan kell használni a scanline és mozog eljárás (palacsinta kérdéses írta funkció) másolata BMP a tömbben. Például én nem is az első sorban nem másolja át (az alábbi kódot nem próbálja másolni az egész BMP egy tömbben, itt látható, hogy még az első sor nem másolja át a tömb):

eljárás TForm1.Button1Click (Sender: TObject);
var b: tbitmap;
i, j: integer;
p: pbytearray;
s: string;
AA: array [0..1024 * 4] bájt;
kezdődik
b: = TBitmap.Create;
b.LoadFromFile ( "F: \ file.bmp");
i: = 0 b.Height-1 do kezdődik
p: = b.ScanLine [i];
lépés (AA, p ^, b.Width);
végén;
végén;

Én nem így csinálni? a harmadik paraméter nem megfelelő eljárás lépés?

Az alábbi kódot, azt kitöltve TBitmapInfo szerkezet, de nem igazán értem, hogy a helyettesítő getdibits funkciót az első paraméter, és ahelyett, hogy egy tömb. Egyes források helyett DC, továbbítja "getdc (0)", hogy "bmp.canvas.handle". És milyen legyen egy tömb?

eljárás TForm1.Button3Click (Sender: TObject);
var
BitInfo1: TBitmapInfo;
b: tbitmap;
dc1: hdc;
AA: array [0..80000] bájt;
s: string;
kezdődik
b: = tbitmap.Create;
b.LoadFromFile ( "F: \ file.bmp");
ZeroMemory (@ BitInfo1, sizeof (BitInfo1));
A bitinfo1.bmiHeader do
kezdődik
biSize: = sizeof (TBITMAPINFOHEADER);
biWidth: = B.Width;
biHeight: = B.Height;
Biplanes: = 1;
biBitCount: = 32;
biCompression: = 0;
biSizeimage: = 0;
biXPelsPerMeter: = 1;
biYPelsPerMeter: = 1;
biClrUsed: = 0;
biClrImportant: = 0;
végén;
GetDIBits (b.Canvas.Handle, b.Handle, 0, 0, @aa, BitInfo1, DIB_RGB_COLORS);
végén;

Itt csinálok rosszul?


eljárás TForm1.Button1Click (Sender: TObject);
var b: tbitmap;
i, j: integer;
p: pbytearray;
s: string;
AA: array [0..1024 * 4] bájt;
kezdődik
b: = TBitmap.Create;
b.LoadFromFile ( "F: \ file.bmp");
i: = 0 b.Height-1 do kezdődik
p: = b.ScanLine [i];
lépés (AA, p ^, b.Width);
végén;
végén;

Ebben a kódot, meg kell állapítanunk, b.pixelFormat és b.Width és b.Height

Nem, nem vagyok zavarodva irányba. Szeretem, és így kell működnie.

típus
TRGBQArray = tömb TRGBQuad;
var


FWidth: = Value.Width;
FHeight: = Value.Height;
SetLength (FA, FHeight * FWidth);
A FInfo.bmiHeader do kezdődik
biWidth: = FWidth;
biHeight: = FHeight;
biSize: = sizeof (TBITMAPINFOHEADER);
biCompression: = BI_RGB;
biBitCount: = 32;
Biplanes: = 1;
biSizeImage: = 0; // ((biWidth * biBitCount + 31) div 32) * biHeight * 4;
végén;
GetDIBits (Value.Canvas.Handle, Value.Handle, 0, FHeight, FA, FInfo, DIB_RGB_COLORS);

2 Jel
Hasonlóképpen, egy palacsinta vegyes forráskódú dest :) (I)
2 Alxx
b.Width és b.Height és b.pixelFormat már definiált, azonnal betöltése után bitmap „és

2 mbo
art létre itt a kód a sablon:

eljárás TForm1.Button4Click (Sender: TObject);
típus
TRGBQArray = tömb TRGBQuad;
var
FA: TRGBQArray;
FInfo: tbitmapinfo;
Érték: TBitmap;
kezdődik
érték: = tbitmap.Create;
value.LoadFromFile ( "d: \ kofe1.bmp");
SetLength (FA, value.Height * value.Width);
A FInfo.bmiHeader do kezdődik
biWidth: = value.Width;
biHeight: = value.Height;
biSize: = sizeof (TBITMAPINFOHEADER);
biCompression: = BI_RGB;
biBitCount: = 24;
Biplanes: = 1;
biSizeImage: = ((value.Width * 24 + 31) div 32) * value.Height * 4; // 0
végén;
GetDIBits (value.Canvas.Handle, Value.Handle, 0, value.Height, FA, FInfo, DIB_RGB_COLORS);
végén;

Lehet, hogy a rossz biSizeImage, de ez nem működik. azaz ha van:
(FA, value.Height * value.Width);
egyértelmű, hogy az a hely, osztottak a tömbben, de miután GetDIBits üres. Azt kell világosan Rosszul.

biSizeImage legyen 0-24 és 32 bites képek

Különös módon helyettesíteni biSizeImage 0, de még mindig azt mutatja, hogy Kedvencekhez üres :(

kód egy működő példa. Biztos vagyok benne, hogy ugyanaz a PixelFormat?

Most, a megbízhatóság egy kicsit változik:

Íme egy példa a statikus tömb


eljárás TForm1.Button2Click (Sender: TObject);
var b: tbitmap;
egy: ​​array [0..9,0..9] a TRGBQuad;
s: string;
info: tbitmapinfo;
i, j: integer;
kezdődik
b: = tbitmap.create;
b.PixelFormat: = pf24bit;
b.width: = 10;
b.height: = 10;
b.Canvas.moveTo (0,0);
b.Canvas.LineTo (6,6);
A info.bmiHeader do kezdődik
biWidth: = b.Width;
biHeight: = b.Height;
biSize: = sizeof (TBITMAPINFOHEADER);
biCompression: = BI_RGB;
biBitCount: = 32;
Biplanes: = 1;
biSizeImage: = 0;
végén;
GetDIBits (b.canvas.handle, B.Handle, 0, B.Height, @ egy, Info, DIB_RGB_COLORS);
i: = 0-tól 9 do kezdeni
s: = "";
j: = 0-tól 9 do s: = s + inttohex (a [i, j] .rgbRed, 2) + "";
memo1.lines.add (s);
végén;
image1.picture.assign (b);
b.free;
végén;

Köszönöm szépen!
A stat. tömb működik.

és dinamikus munkák.
Kezelési lehetőség -
GetDIBits (value.Canvas.Handle, Value.Handle, 0, value.Height, @ FA [0], FInfo, DIB_RGB_COLORS);

Igen, valóban. Köszönet újra.

Az érdekes dolog - bmp.savetostream, gyorsabb kitölti egy sor bájt, mint:

Az alábbi, a oroszlánrészét időt vesz igénybe scanline funkció, ez lehet izbzhat ha juzat Bibliát. G32, de nem lehet telepíteni pixelformat :(

egy: ​​array [0..1023] bájt;
b: array [0..1023 * 768]

j: = 0-1023 do kezdeni
p: = b.scanline [j];
lépés (p ^, a [0], 1024);
i: = j * 1024 * 1024 i1 + 1023 do // összes hozzáadása
b [i]: = a [i-j * 1024]; // az eredeti tömbben
végén;


GetDIBits (bmp.Canvas.Handle, bmp.Handle, 0, bmp.Height, @ FA [0] [0], FInfo, DIB_RGB_COLORS); // FA, din. vagy cikkeket. a tömb nem számít