Using Dephi for image processing can be a variety of methods, the most common should be considered tbitmap, it provides convenient image access, combined with canvas can be drawn line, circle, image copy and other operations. However, in order to get higher speed, we want to be able to read and write directly to the image buffer for a lot of image processing operations. Check the Dephi help manual does not find the ability to directly obtain the entire image buffer, but the provided Scanline property can get a pointer to the specified row image data, closer to our requirements, first look at the description of Scanline:
Provides indexed access to all line of pixels. Property Scanline[row:integer]: Pointer; Description Scanline is used only with DIBs (Device Independent Bitmaps) for image editing tools, do low-level pixel work.
|
Let's look at the relationship between 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, 3 bytes per pixel 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[1])-Integer (bitmap.scanline[0])); MessageBox (Handle, PChar (S),' Scanline ', MB_OK); finally ifAssigned (BITMAP) ThenFreeandnil (BITMAP); end; end;
|
Here is the result of the operation:
Scanline[0]: E90BB8 SCANLINE[1]: E90000 scanline[1]-scanline[0]:-3000 |
The first two results vary depending on the machine, the third result is very special, scanline[0] and scanline[1] The difference between 3000=1000 pixels wide x3 bytes This is easy to understand, but why is negative? Because the BMP image data is "store by row, each line by double word alignment, line in reverse order", that is, the first line of the screen display is stored in the last, the last line of the screen is stored in the front, so use acdsee and so on to see the diagram software to see the larger size of the bitmap when the first display is this truth.
From the above results can be seen tbitmap image data in memory is in line with the reverse order of continuous storage, through tbitmap.scanline[tbitmap.height-1] can get the first address is the image buffer address. Then let's practice, fade the image to black by directly reading and writing to the image buffer:
{====================================================================== DESIGN by: Peng SITE: http://kacarton.yeah.net/ BLOG: Http://blog.csdn.net/nhconch EMAIL: [email protected] article for the author original, please first contact with me, reproduced please indicate the source of the article, retain the author information, thank you for your support! ======================================================================}
procedureTform1.button1click (Sender:tobject); Const Fadeout_step = 24;//Fade out attenuation value Fix_width = 320; Fix_height = 200; var Bitmap:tbitmap; HWINDC:HDC; Flagagein:boolean; Lpbuffer:pbyte;//image buffer Pointer begin BitMap: = tbitmap.create; if notAssigned (BITMAP) ThenExit; try //Set bitmap format, width, height Bitmap.pixelformat: = Pf24bit; Bitmap.width: = Fix_width; Bitmap.height: = Fix_height; //Set the wide charge and height of the form for easy display of results Button1.visible: = false; ClientWidth: = Fix_width; ClientHeight: = Fix_height; //Copy image to bitmap HWINDC: = GetDC (0); if(Hwindc<>null) ThenBitBlt (Bitmap.Canvas.Handle, 0, 0, fix_width, fix_height, HWINDC, 0, 0, srccopy) ElseBitBlt (Bitmap.Canvas.Handle, 0, 0, fix_width, fix_height, canvas.handle, 0, 0, srccopy); Repeat Flagagein: = false; Lpbuffer: = Bitmap.scanline[fix_height-1];//Get image buffer first address //integer (bitmap.scanline[0]) + fix_width*3 End address for image Buffer whileInteger (lpbuffer) < Integer (bitmap.scanline[0]) + fix_width*3Do begin ifLpbuffer^>fadeout_stepThen begin Dec (lpbuffer^, fadeout_step); Flagagein: = true; End Elselpbuffer^: = 0; INC (lpbuffer); Application.processmessages; end; Canvas.draw (0, 0, BITMAP); until( notFlagagein); MessageBox (Handle, ' Done ', ' Fadeout ', MB_OK); finally if Assigned (BITMAP) then Freeandnil (BITMAP); Button1.visible: = true; end; End
|
Finally, add a note:
1, bitmap image buffer is two-section alignment, if the image width of example 1 is changed to 999, a like Motoyuki or 3,000 bytes.
2, at present Bitmap.pixelformat have Pfdevice, Pf1bit, Pf4bit, Pf8bit, Pf15bit, Pf16bit, Pf24bit, Pf32bit, Pfcustom a total of 9 species, The number of bytes per pixel in different formats is different, where the pf4bit and pf8bit format image buffers are saved as color index numbers, the true color values in the palette, the number of bits (bit) that RGB occupies in the pf15bit, pf16bit format is not necessarily equal. Interested in the relevant information can be consulted.
http://blog.csdn.net/nhconch/article/details/68479
Get Tbitmap image buffers to improve image processing speed