The Application of GDI + in the Delphi Program-there are many ways to adjust the brightness of an image, the most common method is to increase or decrease a certain value at the same time for the R, G, and B components of the image pixel to adjust the brightness. Here I use the Scan Line of the GDI + image for processing. The core processing adopts two identical processes, one is the PASCAL process, and the other is the embedded assembly process. Through comparison, there is almost no difference in small images, and there are still some differences in processing large images (for specific test results, see the comments in the Code). This shows that Delphi's code optimization is still very good. Tgpbitmap must be called for processing scanned lines using GDI + images. lockbits and tgpbitmap. the unlockbits process, and the call of these two processes is quite time-consuming. Taking an image of 2304*1728 as an example, the time consumption actually reached 188 milliseconds! However, the brightness adjustment process takes up to 63 milliseconds. From this we can see that using GDI + image scanning lines to process images is not ideal. It should be noted that the gdiplus unit in this example and in the subsequent examples of GDI + for Delphi is self-written, which is different from the current versions available on the Internet. You need to refer to the example to be tested, you can modify the settings or send an email to request the gdiplus unit. Note: In order to unify the data types and image processing formats used in the "Application of GDI + in Delphi" series of articles, the code in this article has been revised, for details about the gdiplus unit and bug correction used in the code, see the article "GDI + for VCL basics-GDI + and VCL". Data Type:
- Type
- // Image data structure compatible with the GDI + tbitmapdata Structure
- Timagedata = packed record
- Width: longword; // The image width.
- Height: longword; // Image Height
- Stride: longword; // The length of the scanned line of the image in bytes.
- Pixelformat: longword; // unused
- Scan0: pointer; // image data address
- Reserved: longword; // Reserved
- End;
- Pimagedata = ^ timagedata;
- // Obtain the timagedata data structure of the tbitmap image to facilitate the processing of the tbitmap Image
- Function getimagedata (BMP: tbitmap): timagedata;
- Begin
- BMP. pixelformat: = pf32bit;
- Result. Width: = BMP. width;
- Result. Height: = BMP. height;
- Result. scan0: = BMP. scanline [BMP. Height-1];
- Result. stride: = result. Width SHL 2;
- // Result. stride: = (32 * BMP. width) + 31) and $ ffffffe0) SHR 3;
- End;
Process Code:
- // Adjust the image brightness
- Procedure brightness (data: timagedata; Value: integer );
- ASM
- Push ESI
- Push EDI
- MoV EDI, [eax + 16]
- MoV ESI, [eax + 4]
- Imul ESI, [eax]
- ClD
- @ Pixelloop:
- MoV ECx, 3
- @ Rgbloop:
- Movzx eax, [EDI]
- Add eax, EDX
- JNS @ 1
- XOR eax, eax
- JMP @ 2
- @ 1:
- CMP eax 255
- Jle @ 2
- MoV eax, 255
- @ 2:
- Stosb
- Loop @ rgbloop
- INC EDI
- Dec ESI
- Jnz @ pixelloop
- Pop EDI
- Pop ESI
- End;
- // Adjust the GDI + image brightness
- Procedure gdipbrightness (BMP: tgpbitmap; Value: integer );
- VaR
- Data: tbitmapdata;
- Begin
- If value = 0 Then exit;
- Data: = BMP. lockbits (gprect (0, 0, BMP. Width, BMP. Height), [imread, imwrite], pf32bppargb );
- Try
- Brightness (timagedata (data), value );
- Finally
- BMP. unlockbits (data );
- End;
- End;
- // Adjust the brightness of the tbitmap Image
- Procedure bitmapbrightness (BMP: tbitmap; Value: integer );
- Begin
- If value <> 0 then
- Brightness (getimagedata (BMP), value );
- End;
Test code:
- // To help beginners understand the BaSm code, write a pure pas code process for processing the GDI + image brightness.
- // You can change the brightness of a tbitmap image.
- Procedure gdipbrightness_pas (BMP: tgpbitmap; Value: integer );
- Function setrgbvalue (RGB: byte): integer;
- Begin
- Result: = value + RGB; // pixel color component + Brightness Value
- If result <0 then // pixel color component> = 0 and <= 255
- Result: = 0
- Else if Result & gt; 255 then
- Result: = 255;
- End;
- VaR
- Data: tbitmapdata;
- P: prgbquad;
- I, Count: longword;
- Begin
- If value = 0 Then exit;
- Data: = BMP. lockbits (gprect (0, 0, BMP. Width, BMP. Height), [imread, imwrite], pf32bppargb );
- Try
- Count: = data. Width * Data. height;
- P: = data. scan0;
- For I: = 1 to count do
- Begin
- P ^. rgbblue: = setrgbvalue (P ^. rgbblue );
- P ^. rgbgreen: = setrgbvalue (P ^. rgbgreen );
- P ^. rgbred: = setrgbvalue (P ^. rgbred );
- INC (P );
- End;
- Finally
- BMP. unlockbits (data );
- End;
- End;
- // Test the GDI + image
- Procedure tform1.button1click (Sender: tobject );
- VaR
- Image: tgpbitmap;
- G: tgpgraphics;
- Begin
- Image: = tgpbitmap. Create ('d:/vcllib/gdiplusdemo/Media/20041001.jpg ');
- G: = tgpgraphics. Create (handle, false );
- G. drawimage (image, 10, 10 );
- // Gdipbrightness_pas (image, 30 );
- Gdipbrightness (image, 30 );
- G. drawimage (images, 10,220 );
- Image. Free;
- G. Free;
- End;
- // Test the tbitmap Image
- Procedure tform1.button2click (Sender: tobject );
- VaR
- Image: tbitmap;
- Begin
- Image: = tbitmap. Create;
- Image. loadfromfile ('d:/vcllib/gdiplusdemo/Media/20041001.bmp ');
- Canvas. Draw (10, 10, image );
- Bitmapbrightness (image,-30 );
- Canvas. Draw (10,220, image );
- Image. Free;
- End;