Cum se copiază un bitmap într-o matrice de octet

Cum se copiază un bitmap într-o matrice de octet?

De preferință, folosind funcția de mutare (care a fost mai rapid), o savetostream apoi foarte lent. Asta este tot.

Lucrați cu și prin pixelii pot bitmap.canvas.pixels [x, y], ci mai degrabă prin scanline.







GetDiBits
GetBitmapBits (vechi, dar funcționează)

bitmap.canvas.pixels [x, y] - ruleaza mai lent decât savetostream.
un modul de utilizare a procedurii scanline și mutare (clătite în cauză a scris funcția) copie a BMP în matrice. De exemplu, eu nu chiar prima linie nu este copiat (codul de mai jos nu este încercarea de a copia întregul BMP într-o matrice, se arată aici, că, chiar și prima linie nu este copiat în matrice):

Procedura TForm1.Button1Click (Expeditor: TObject);
var b: tbitmap;
i, j: integer;
p: pbytearray;
s: string;
aa: array [0..1024 * 4] de octet;
începe
b: = TBitmap.Create;
b.LoadFromFile ( "f: \ file.bmp");
pentru i: = 0 până la b.Height-1 do începe
p: = b.ScanLine [i];
muta (aa, p ^, b.Width);
se încheie;
se încheie;

Nu sunt așa să fac? este al treilea parametru este incorectă procedură mișcare?

în codul de mai jos, am umplut structura TBitmapInfo, dar nu înțeleg cu adevărat că substitutului în funcția getdibits în primul parametru, și în loc de o matrice. Unele surse în loc de DC, transmite "getdc (0)" la "bmp.canvas.handle". Si ce fel ar trebui să fie o matrice?

Procedura TForm1.Button3Click (Expeditor: TObject);
var
BitInfo1: TBitmapInfo;
b: tbitmap;
DC1: HDC;
aa: array [0..80000] de octet;
s: string;
începe
b: = tbitmap.Create;
b.LoadFromFile ( "f: \ file.bmp");
ZeroMemory (@ BitInfo1, sizeof (BitInfo1));
cu bitinfo1.bmiHeader do
începe
biSize: = sizeof (TBITMAPINFOHEADER);
biWidth: = B.Width;
biHeight: = B.Height;
biplane: = 1;
biBitCount: = 32;
biCompression: = 0;
biSizeimage: = 0;
biXPelsPerMeter: = 1;
biYPelsPerMeter: = 1;
biClrUsed: = 0;
biClrImportant: = 0;
se încheie;
GetDIBits (b.Canvas.Handle, b.Handle, 0, 0, @aa, BitInfo1, DIB_RGB_COLORS);
se încheie;

aici am făcut greșit?


Procedura TForm1.Button1Click (Expeditor: TObject);
var b: tbitmap;
i, j: integer;
p: pbytearray;
s: string;
aa: array [0..1024 * 4] de octet;
începe
b: = TBitmap.Create;
b.LoadFromFile ( "f: \ file.bmp");
pentru i: = 0 până la b.Height-1 do începe
p: = b.ScanLine [i];
muta (aa, p ^, b.Width);
se încheie;
se încheie;

În acest cod, aveți nevoie pentru a determina b.pixelFormat și b.Width și b.Height







Nu, sunt direcția confuză. Îmi place și așa ar trebui să funcționeze.

tip
TRGBQArray = array de TRGBQuad;
var


FWidth: = Value.Width;
FHeight: = Value.Height;
Setlength (FA, FHeight * FWidth);
cu FInfo.bmiHeader do începe
biWidth: = FWidth;
biHeight: = FHeight;
biSize: = sizeof (TBITMAPINFOHEADER);
biCompression: = BI_RGB;
biBitCount: = 32;
biplane: = 1;
biSizeImage: = 0; // ((biWidth * biBitCount + 31) div 32) * biHeight * 4;
se încheie;
GetDIBits (Value.Canvas.Handle, Value.Handle, 0, FHeight, FA, FInfo, DIB_RGB_COLORS);

2 Jel
In mod similar, o clătită cu dest sursa mixta :) (I)
2 Alxx
b.Width și b.Height și b.pixelFormat deja definit, imediat după încărcarea unui bitmap „și

2 MBO
arta creată aici este codul pentru șablonul:

Procedura TForm1.Button4Click (Expeditor: TObject);
tip
TRGBQArray = array de TRGBQuad;
var
FA: TRGBQArray;
FInfo: tbitmapinfo;
Valoare: TBitmap;
începe
Valoarea: = tbitmap.Create;
value.LoadFromFile ( "d: \ kofe1.bmp");
Setlength (FA, value.Height * value.Width);
cu FInfo.bmiHeader do începe
biWidth: = value.Width;
biHeight: = value.Height;
biSize: = sizeof (TBITMAPINFOHEADER);
biCompression: = BI_RGB;
biBitCount: = 24;
biplane: = 1;
biSizeImage: = ((value.Width * 24 + 31) div 32) * value.Height * 4; // 0
se încheie;
GetDIBits (value.Canvas.Handle, Value.Handle, 0, value.Height, FA, FInfo, DIB_RGB_COLORS);
se încheie;

S-ar putea avea biSizeImage greșit, dar aceasta nu funcționează. și anume atunci când există:
(FA, value.Height * value.Width);
este clar că locul a fost alocat în matrice, dar după GetDIBits gol. Trebuie să fi ajuns în mod clar greșit.

biSizeImage ar trebui să fie între 0 și 24 și pe 32 de biți imagini

Destul de ciudat, înlocuit biSizeImage la 0, dar încă arată că lista de Urmărit gol :(

Codul de un exemplu de lucru. Sunt sigur că aceeași PixelFormat?

Acum, pentru fiabilitatea puțin modificată:

Iată un exemplu de matrice statică


Procedura TForm1.Button2Click (Expeditor: TObject);
var b: tbitmap;
a: array [0..9,0..9] de TRGBQuad;
s: string;
info: tbitmapinfo;
i, j: integer;
începe
b: = tbitmap.create;
b.PixelFormat: = pf24bit;
b.width: = 10;
b.height: = 10;
b.Canvas.moveTo (0,0);
b.Canvas.LineTo (6,6);
cu info.bmiHeader do începe
biWidth: = b.Width;
biHeight: = b.Height;
biSize: = sizeof (TBITMAPINFOHEADER);
biCompression: = BI_RGB;
biBitCount: = 32;
biplane: = 1;
biSizeImage: = 0;
se încheie;
GetDIBits (b.canvas.handle, B.Handle, 0, B.Height, @ a, Info, DIB_RGB_COLORS);
pentru i: = 0 până la 9 nu începe
s: = "";
pentru j: = 0 până la 9 do s: = s + inttohex (a [i, j] .rgbRed, 2) + "";
memo1.lines.add (s);
se încheie;
image1.picture.assign (b);
b.free;
se încheie;

Vă mulțumesc foarte mult!
Cu Stat. o matrice de lucrări.

și lucrări dinamice.
Tratamentul Opțiunea -
GetDIBits (value.Canvas.Handle, Value.Handle, 0, value.Height, @ FA [0], FInfo, DIB_RGB_COLORS);

Da, într-adevăr. Mulțumesc din nou.

Lucrul interesant este - bmp.savetostream, mai rapid umple o serie de octeți, decât:

de mai jos, partea leului de timp are funcția scanline, acest lucru poate fi izbzhat dacă juzat Bibliei. pixelformat G32, dar nu pot fi instalate :(

a: array [0..1023] de octet;
b: array [0..1023 * 768]

pentru j: = 0-1023 nu începe
p: = b.scanline [j];
mutare (p ^, o [0], 1024);
pentru i: = j * 1024 * 1024 i1 + 1023 do // adauga toate
b [i]: = a [i-j * 1024]; // în matrice originală
se încheie;


GetDIBits (bmp.Canvas.Handle, bmp.Handle, 0, bmp.Height, @ FA [0] [0], FInfo, DIB_RGB_COLORS); // FA, DIN. sau articole. matrice nu contează