Cum se scrie rapid un octet într-un fișier

Cum se scrie rapid un octet într-un fișier?

Iată procedura:
assignfile (flb, currpath + f_GrayTMP);
# xA0; resetare (flb);
# xA0; Căutați (flb, 1078);

# xA0; count: = imagine1.Picture.Bitmap.Width * image1.Picture.Bitmap.Height;






# xA0; pix_p: = imagine1.Picture.Bitmap.RawImage.data;
# xA0; dacă image1.Picture.Bitmap.pixelformat = pf32bit atunci
# xA0; începeți
# xA0; # xA0; pix4out: = pix_p;
# xA0; # xA0; inc (pix4out, număr);
# xA0; # xA0; repetați
# xA0; # xA0; # xA0; scrieți (flb, pix4out ^ .rgbRed);
# xA0; # xA0; # xA0; dec (pix4out);
# xA0; # xA0; # xA0; dec (număr);
# xA0; # xA0; până la număr<=0;
# xA0; sfârșitul; # xA0; # xA0; # xA0;

foarte încet scrie într-un fișier (fișier de 800 kb secunde 3-4).
cum să accelereze?

eu folosesc # xA0; FPC 2.6, dar cred că problema nu este în compilator, ci în abordare

Byte nu este rapid.
rapid non-octet

Se pare că codul scrie o fișă de memorie inversă în fișier. Pentru viteză, este mai bine să o răsturnați într-o matrice, apoi să scrieți întreaga matrice într-un fișier - bucăți mari sunt scrise mai repede.

Ei bine sau da
mai întâi creați o memorie de 800kb, apoi completați-o, apoi scrieți-o în fișier

modificat la o matrice, # xA0; BlockWrite (flb, pix_map [0], dimensiunea (pix_map [0]) * număr); nimic nu este scris în fișierul :(
# xA0; assignfile (flb, currpath + f_GrayTMP);
# xA0; resetare (flb);
# xA0; Căutați (flb, 1078);
# xA0; count: = image1.Picture.Bitmap.Width * image1.Picture.Bitmap.Height;
# xA0; setlength (pix_map, număr);
# xA0; i: = 0;
# xA0; pix_p: = imagine1.Picture.Bitmap.RawImage.data;
# xA0; dacă image1.Picture.Bitmap.pixelformat = pf32bit atunci
# xA0; începeți
# xA0; # xA0; pix4out: = pix_p;
# xA0; # xA0; inc (pix4out, număr);
# xA0; # xA0; repetați
# xA0; # xA0; pix_map [i]: = pix4out ^ .rgbRed;
# xA0; # xA0; dec (pix4out);
# xA0; # xA0; dec (număr);
# xA0; # xA0; inc (i);
# xA0; # xA0; până la număr<=0;
# xA0; sfârșitul; # xA0; # xA0; # xA0; # xA0; # xA0; # xA0; # xA0;

BlockWrite (flb, pix_map [0], dimensiunea (pix_map [0]) * număr);
închis fișier (flb);

resetare (flb);
resetare are un al doilea parametru

numărați după ciclu ceea ce este?

În general, aici bucla pentru este mai potrivită

Acum este imposibil să scrieți o matrice dinamică într-un fișier, matricea este scrisă mai precis, dar în fișier există un zer, în debugger datele din matrice sunt
assignfile (flb, currpath + f_GrayTMP);
# xA0; resetare (flb, 1);
# xA0; Căutați (flb, 1078);
# xA0; count: = imagine1.Picture.Bitmap.Width * image1.Picture.Bitmap.Height;
# xA0; setlength (pix_map, număr);
# xA0; i: = 0;
# xA0; pix_p: = imagine1.Picture.Bitmap.RawImage.data;
# xA0; dacă image1.Picture.Bitmap.pixelformat = pf32bit atunci
# xA0; începeți
# xA0; # xA0; pix4out: = pix_p;
# xA0; # xA0; inc (pix4out, număr);
# xA0; # xA0; pentru i: = 0 la numărul-1 face
# xA0; # xA0; începeți
# xA0; # xA0; # xA0; pix_map [i]: = pix4out ^ .rgbRed;
# xA0; # xA0; # xA0; dec (pix4out);
# xA0; # xA0; se încheie;
# xA0; sfârșitul;
BlockWrite (flb, pix_map [0], lungime (pix_map));
închis fișier (flb);
pix_map: = NIL; # xA0; # xA0; # xA0; # xA0; # xA0; # xA0; # xA0; # xA0; # xA0; # xA0; # xA0; # xA0; # xA0;

variabilele sunt declarate # xA0;
flb: fișier;
# xA0; pix_map: matrice de octeți;
De ce sunt scrise valorile zero?

Și într-un dosar, în general, ceva este scris? Este fișierul deschis pentru înregistrare?

Vechile metode de lucru cu fișiere de avantaje față de TFileStream nu au, deci este rezonabil să treci la acesta din urmă.







Fișierul este scris, mărit de dimensiunea matricei, dar toate zerouri.
În acest moment voi încerca să curgă

și în ce ordine ar trebui să aveți octeți în pix_map?

Și, în general, ia notă de notă:

funcția BitmapLineSize (const Bitmap: TBitmap): integer;
const
# XA0; // (pfDevice, pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, pf24bit, pf32bit, pfCustom)
# XA0; PIXEL_SIZES: array [TPixelFormat] integer = (0, 1, 4, 8, 16, 16, 24, 32, 0);
începe
# XA0; Rezultat: = ((PIXEL_SIZES [Bitmap.PixelFormat] * Bitmap.Width + 31) și -32) SHR 3);
se încheie;


# xA0; BitmapData: NativeInt;
# xA0; LinearSize: întreg;
# xA0; X, Y: întreg;
# xA0; Pixel: PRGBQuad; // pentru pf32bit
.
# xA0; BitmapData: = NativeInt (Bitmap.ScanLine [0]);
# xA0; LinearSize: = -BitmapLineSize (Bitmap);
# xA0;
# xA0; // bucla cu acces X / Y
# xA0; pentru Y: = 0 la Bitmap.Height-1 nu
# xA0; pentru X: = 0 la Bitmap.Width-1 face
# xA0; începeți
# xA0; # xA0; Pixel: = Indicator (BitmapData + Y * LinearSize + X * sizeof (TRGBQuad));
# xA0; # xA0; //.
# xA0; sfârșitul;

Există același Graphics.BytesPerScanline.

Sarcina este: faceți o fotografie (32 de biți, adică alinierea nu trebuie luată în considerare), convertiți-o în nuanțe de gri și salvați-o în 8 biți cu o paletă.
Nu am găsit în cazul în care CFP poate crea o clasă paletă bitmap, pentru că doar a scrie într-un fișier, în primul rând antet cu o paletă, urmat de indicii înșiși în ordine inversă pentru a deschide bitmap

Am decis că era mai ușor. Când baza este linia [0]
În plus, nu este nevoie să vă scăldați cu manipulările de răsturnare a Y de la Height

> Sapersky (20.11.13 14:32) [15]
> Există același Graphics.BytesPerScanline.

Înțelesul este același, acțiunile sunt mai puțin

> Am decis că este mai ușor. Când baza este linia [0]

Dar linia zero nu se află întotdeauna la sfârșit

> Vasya (20.11.13 14:34) [16]
> Sarcina este: să faceți o fotografie (32 biți, adică aliniere
> nu trebuie să ia în considerare), convertiți-l în tonuri de gri
> și salvați la 8 biți cu o paletă.
> Nu am găsit unde în FPC este posibil să creați o paletă în clasa bitmap,
> # xA0; deoarece scrieți doar fișierul în primul antet cu o paletă,
> # xA0; în spatele ei sunt indexați ele însele în ordine inversă față de bitmapul deschis

De asemenea, veți avea nevoie de fișierul rezultat în formatul Bitmap. linii de la partea de sus în sus + alinierea cu 4 octeți

var
# xA0; Lățimea, înălțimea, X, Y: întreg;
# xA0; Gap;
# xA0; Pixeli, dest: pbyte;
# xA0; src: PRGBQuad; # xA0;
începe
# xA0; Lățime: = Bitmap.Width;
# xA0; Înălțime: = Bitmap.Height;
# xA0; GetMem (Pixeli, ((Lățime + 3) și -4) * Înălțime);
# xA0; Gap: = ((Lățime + 3) și -4) - Lățime;
# xA0;
# xA0; dest: = Pixeli;
# xA0; src: = Bitmap.ScanLine [Înălțimea-1];
# xA0; pentru Y: = 0 până la Înălțimea-1 face
# xA0; începeți
# xA0; # xA0; pentru X: = 0 până la Width-1
# xA0; # xA0; începeți
# xA0; # xA0; # xA0; // algoritmul gri
# xA0; # xA0; # xA0; dest ^: = src.rgbRed;
# xA0; # xA0;
# xA0; # xA0; # xA0; // următorul pixel
# xA0; # xA0; # xA0; inc (src);
# xA0; # xA0; # xA0; inc (dest);
# xA0; # xA0; sfârșitul;

Ai dreptate. În practică, nu am văzut astfel de fișiere, dar judecând după codul sursă Graphics, o astfel de probabilitate este

Deci:
funcția BitmapLinearSize (const Bitmap: TBitmap): integer;
începe
# xA0; dacă (Bitmap.Heigth <= 1) then Result := 0
# xA0; altceva
# xA0; Rezultat: = NativeInt (Bitmap.ScanLine [1]) - NativeInt (Bitmap.ScanLine [0]);
se încheie;


> În practică, nu am văzut astfel de fișiere

Puteți să-l utilizați singur, deoarece mai devreme sau mai târziu vă veți plictisi de această inversă.
Dar în TBitmap (cel puțin versiuni mai vechi) este într-un fel controversat făcut. Dacă setați o înălțime negativă - bitmap-ul va fi "normal", dar înălțimea va rămâne pozitivă. poate în versiuni mai noi este mai bine.

> Sapersky (20.11.13 15:03) [21]

Ei bine rață cum înălțimea imaginii (TBitmap.Height) poate fi negativă? Este întotdeauna pozitivă. Și biHeight intern este deja folosit așa cum ar trebui cu ScanLine

funcția TBitmap.GetHeight: Integer;
începe
# xA0; Rezultat: = Abs (FImage.FDIB.dsbm.bmHeight);
se încheie;

Când am încercat, biheight intern sau bmHeight ar părea, de asemenea, pozitive și, ca rezultat, GetScanline a funcționat incorect.

Întrebarea este: cum să scrieți în mod corespunzător un tablou într-un fișier?

> Vasya (20.11.13 17:28) [25]
> Întrebarea în alta: cât de corect să scriem o matrice într-un fișier?

în mod normal, sunteți înregistrat
nu o completați
puteți de dragul testului completați-l cu o valoare de exemplu de 255 înainte de a scrie


> nu o completați

într-adevăr nu umple, contra de ciclu cu un fel de frică determinat i: byte; schimbat la întreg, totul a funcționat, cu excepția cazului în care compilatorul nu ar trebui să indice această eroare?

Vă recomandăm din nou să înțelegeți înțelegerea locației liniilor

deoarece aveți o umplere de la început până la sfârșit, de la sfârșitul la început, nu există nici o aliniere de 4 octeți. ceea ce va duce la o muncă incorectă







Trimiteți-le prietenilor: