Get the Tbitmap image buffer to improve image processing speed

zhaozj2021-02-16  126

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:

{================================================================================================================================================================================================================ ===================== Design By: Peng Guohui Site: http://kacarton.yeah.net/ blog: http://blog.9cbs.net/nhconch Email: kacarton@sohu.com Article Original, please contact me before reprinting, please indicate the article, retain the author information, thank you for your support! ============================================================================================================================================================================================================= ========================================================================================================================== # 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 width of Form filling height, the results for display 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) FADEOUT_STEP then begin Dec (lpBuffer ^, FADEOUT_STEP); flagAgein: = true; end else lpBuffer ^: = 0 ; INC ;., can, canvas.draw (0, 0, bitmap); until (not flagagein); messagebox (Handle, 'DONE', 'FADEOUT', MB_OK); Finally IF Assigned (Bitmap) "bitmap); button1.visible: = true; end; end; finally added : 1, the Bitmap image buffer is two-section alignment, and if the image width in Example 1 is changed to 999, a pixel row is still 3000 bytes. 2, current Bitmap.pixelformat has 9 pfDevice, pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, pf24bit, pf32bit, PFCUSTOM total, different bytes per pixel per pixel, where PF4BIT and PF8BIT format are saved For color index marks, the real color value is in the palette, the number of bits (bits) occupying the RGB in the PF15bit, and the PF16bit format is not necessarily equal. Interested in consulting the relevant information.

转载请注明原文地址:https://www.9cbs.com/read-8061.html

New Post(0)