Image processing using DEPHI can have a variety of methods, the most commonly used TbitMap, provides convenient image access capability, combined with Canvas, draw circles, image copying and other operations. However, in order to obtain a large number of image processing, we hope to read and write the image buffer directly. Check out the DEPHI's Help Manual No found the functionality that directly acquires the entire image buffer, but the SCANLINE attribute provided can get a pointer to specify line image data, which is close to our requirements, first look at Scanline description:
Provides indexed access to each line of pixels.property ScanLine [Row: Integer]: Pointer; DescriptionScanLine is used only with DIBs (Device Independent Bitmaps) for image editing tools that do low-level pixel work.
Let's take a look at Scanline [0], Scanline [1]:
Procedure tForm1.Button1Click (Sender: Tobject); var Bitmap: Tbitmap; s: string; begin bitmap: = tbitmap.create; try bitmap.pixelformat: = PF24bit; // 24 bit color, each pixel point 3 byte Bitmap. Width: = 1000; Bitmap.Height: = 2; FMTSTR (s, 'scanline [0]:% 8x' # 13'scanline [1]:% 8x '# 13'scanline [1] -scanline [0]:% D ', [INTEGER (Bitmap.scanline [0]), Integer (Bitmap.scanline [1]), Integer (Bitmap.scanline [0])]); MessageBox (Handle, PCHAR (S), 'Scanline', MB_OK; Finally if Assigned (Bitmap) THEN FreeAndnil (Bitmap); End; End;
Below is the result:
Scanline [0]: e90bb8scanline [1]: e90000scanline [1] -scanline [0]: - 3000
The first two results are different from the machine, and the third result is very special. Scanline [0] is different from scanline [1] 3000 = 1000 pixels wide × 3 bytes This is easy to understand, but why is it negative? Because BMP image data is "in line storage, each line is aligned, the line is stored in reverse order", that is, the first row of the screen is stored in the final, the last line of the screen is stored in front, so use ACDSEE Waiting for the picture software to see the size of a large bitmap, starting from the lower part to this truth. From the above results, it can be seen that the image data of TBITMAP is continuously stored in the memory, and the image buffer address can be obtained by tbitmap.scanline [TbitMap.Height-1]. Then let's practice, pass the image directly to black by directly reading and writing of the image buffer:
procedure TForm1.Button1Click (Sender: TObject); const FADEOUT_STEP = 24; // fade attenuation FIX_WIDTH = 320; FIX_HEIGHT = 200; var BitMap: TBitmap; hWinDC: HDC; flagAgein: Boolean; lpBuffer: PByte; // image buffer Pointer Begin Bitmap: = tbitmap.create; if not assigned (bitmap) THEN EXIT; TRY / / Setting bitmap format, width, height bitmap.pixelformat: = pf24bit; bitmap.width: = fix_width; bitmap.height: = fix_height; // Set the Wide charge, height of the Form, easy to display the result button1.visible: = false; clientwidth: = fix_width; clientHeight: = fix_height; // Copy image to Bitmap hwindc: = getDC (0); if (Hwindc <> Null) The Bitblt (Bitmap.canvas.Handle, 0, 0, Fix_Width, Fix_HEight, Hwindc, 0, 0, Srcopy Else Bitblt (Bitmap.canvas.Handle, 0, 0, Fix_Width, Fix_Height, Canvas.Handle, 0, 0, srcopy; = false; lpbuffer: = bitmap.scanline [fix_height-1]; // acquired image buffer first address //integer (bitmap.scanline[0]) fix_width * 3 is image buffer End address while Integer (lpBuffer)