1. About GDI +
In essence, GDI + provides developers with a set of implementations and various devices (such as monitors, printers, and other devices with graphical capabilities but less than those with graphic details) library functions for interaction. The essence of GDI + is that it can replace developers to achieve interaction with monitors and other peripherals. From the developer's point of view, it is an arduous task to achieve direct interaction with these devices.
1 demonstrate that GDI + plays an important intermediary role between developers and the above-mentioned devices. Among them, GDI + "arranged" almost everything for us-from printing a simple string "helloworld" to the console to drawing a straight line, a rectangle or even printing a complete form.
Figure 1.gdi+ plays an important intermediary role
So how does GDI + work? To solve this problem, let's analyze an example-draw a line segment. Essentially, a line segment is a collection of pixels from a starting position (x0, y0) to an ending position (Xn, yn. To draw such a line segment, the device (in this example, the monitor) needs to know the corresponding device coordinates or physical coordinates.
However, developers do not directly tell the device, but call the drawline () method of GDI +, and then, ") draw a straight line from point A to B. GDI + reads the positions of vertices A and vertices B, converts them into a pixel sequence, and the command monitor displays the pixel sequence. In short, GDI + converts independent device calls into a device's understandable form, or converts devices in the opposite direction.
So far, we have briefly understood the working mechanism of GDI +. Now let's start to explore how to implement some basic image operations.
Ii. Image operations-thumbnails, scaling and storage
In this example, we will implement the following tasks:
1. Create a thumbnail.
2. Scale A loaded image.
3. save an image in the operation.
A) create a thumbnail.
Thumbnail is the concentrated version of the image. In typical cases, the size of a thumbnail image is 80x200 pixels. In GDI +, a thumbnail of an image can be created by using the getthumbnailimage () method of the image class. The function prototype is as follows:
Public Image getthumbnailimage (
Int thumbwidth,
Int thumbheight,
Getthumbnailimageabort callback,
Intptr callbackdata
)
|
The first parameter corresponds to the width of the thumbnail, the second parameter corresponds to the height of the generated thumbnail, and the third parameter is an image. getthumbnailimageabort delegate. This delegate is not used in GDI + 1.0. Even so, you must create a delegate and pass a reference to the delegate in this parameter. The fourth parameter is also not used, but must be provided for compatibility. Note that the fourth parameter must be intptr. Zero.
If the first two parameters (that is, the width and height) are both 0, then GDI + returns an embedded thumbnail. Otherwise, use the system-defined size to create the thumbnail. For example, if IMG is an image class instance and its width and height are all defined by the system, the statement for creating a thumbnail should be as follows:
Image thumbnailimage = IMG. getthumbnailimage (0, 0, tncallback, intptr. Zero );
|
Here, thumbnailimage contains the thumbnail returned, and tncallback is a function corresponding to image. getthumbnailimageabort, which is defined as follows:
// It must be called but not used
Style = 'font-size: 10.0pt; font-family: verdana '> publicbool tncallbackmethod ()
...{
Return false;
}
|
B) scale a loaded image.
Scaling is the process of enlarging or downgrading an image-achieved by increasing the image size with a scaling factor. Here, the scaling factor = the expected image size/current image size. For example, to enlarge an image by 200%, the current size must be multiplied by 200% (200% = 200/100 = 2). To reduce an image to 25%, the current size must be multiplied by 25% or 0.25 (25/100 = 0.25 times ).
C) Save the image
The Save operation is one of the key operations in image operations. When saving an image, the corresponding image type information must also be saved; that is, the image extension plays an important role in this process. Each type corresponds to a specific format. In essence, it is necessary to output data according to the format when saving an image. However, with the advantage of GDI + API, a simple call to the SAVE () method of the image class can omit all the details of the corresponding write data operation. This method uses two parameters: the name of the saved image and the format of the image to be saved. The format can be specified through the type provided by the imageformat class. The following table specifies various image formats supported by GDI +.
Attribute description
BMP specifies the BMP format.
EMF specifies the EMF (Enhanced Metadata File Format ).
EXIF specifies the EXIF format.
GIF: Specifies the GIF format.
Guid specifies a guid structure used to describe imageformatobject.
Icon specifies the Windows icon format.
JPEG specifies the JPEG format.
Memorybmp specifies the memory bitmap format.
PNG specifies the PNG format.
Tiff specifies the TIFF format.
WMF specifies the WMF Format ).
EMF and WMF are specific to Windows systems.
If you want to save an image using the “checker.gif name, the corresponding implementation statement will be:
Curimage.save(+checker.gif ", imageformat. GIF );
|
Here, curimage corresponds to an image class instance.
In the next section, I willProgram.
Iii. Image operations in actual development
Next, we will discuss the actual usage. I will add the following features to the example application in this article:
1. Save the image in the format specified by the user.
2. Enlarge the image based on the percentage selected from the menu.
3. Create a thumbnail for loading images.
The corresponding menu operations are as follows:
Mnusave-sub menu for saving images under the File menu.
Mnu200zoom-zoom in image 200%.
Mnuthumbnail-create a thumbnail of the image.
The following describes how to handle the Click Event of the menu item mnusave:
Private void mnusave_click (Object sender, system. eventargs E)
...{
// If the image has been created
If (curimage = NULL)
Return;
// Call the savefiledialog dialog box
Savefiledialog savedlg = new savefiledialog ();
Savedlg. Title = "Save image ";
Savedlg. overwriteprompt = true;
Savedlg. checkpathexists = true;
Savedlg. Filter =
"Bitmap file (*. BMP) | *. BMP |" +
"GIF file (*. GIF) | *. gif |" +
"JPEG file (*. jpg) | *. jpg |" +
"PNG file (*. PNG) | *. PNG ";
Savedlg. showHelp = true;
// If selected, save
If (savedlg. showdialog () = dialogresult. OK)
...{
// Obtain the selected file name
String filename = savedlg. filename;
// Get the file extension
String strfilextn = filename. Remove (0, filename. Length-3 );
// Save the file
Switch (strfilextn)
...{
Case "BMP ":
Curimage. Save (filename, imageformat. BMP );
Break;
Case "jpg ":
Curimage. Save (filename, imageformat. JPEG );
Break;
Case "GIF ":
Curimage. Save (filename, imageformat. GIF );
Break;
Case "TIF ":
Curimage. Save (filename, imageformat. Tiff );
Break;
Case "PNG ":
Curimage. Save (filename, imageformat. PNG );
Break;
Default:
Break;
}
}
} |
First, the SAVE dialog box is displayed with a printable extension. Then, the corresponding extension is retrieved from the file name returned by the dialog box. Finally, the SAVE () method is called using the corresponding image format parameters based on the extension.
Next, we will analyze the processor corresponding to the menu item mnu200zoom. First, let's add the following line in bold at the application level:
Private double curzoom = 1.0;
Private image curimage = NULL; // used to store the current image
Private int I = 0; // used to distinguish screen repainting from thumbnail painting.
Then, mnuload must be processed. Code Make a few adjustments as follows:
Private void mnuload_click (Object sender, system. eventargs E)
...{
// Create openfiledialog
Openfiledialog opndlg = new openfiledialog ();
// Set an image filter
Opndlg. Filter =
"All image files | *. BMP; *. gif; *. jpg; *. ICO;" +
"*. EMF;, *. WMF | bitmap files (*. BMP; *. gif; *. jpg;" +
"*. Ico) | *. BMP; *. gif; *. jpg; *. ICO |" +
"Meta files (*. EMF; *. WMF; *. PNG) | *. EMF; *. WMF; *. PNG ";
Opndlg. Title = "open image file ";
Opndlg. showHelp = true;
// If OK, select it
If (opndlg. showdialog () = dialogresult. OK)
...{
// Read the selected file name
Curfilename = opndlg. filename;
// Use image. fromfile to create an image object
Try
...{
Curimage = image. fromfile (curfilename );
}
Catch (exception exp)
...{
MessageBox. Show (exp. Message );
}
}
// Modify the autoscrollminsize attribute
This. autoscrollminsize = new size
(INT) (curimage. Width * curzoom ),
(INT) (curimage. Height * curzoom ));
I ++;
// Redraw the form
Invalidate ();
} |
Note that the code added here is superior to the original image width and height to generate a magnified image. Then, the processor of the paint event must be modified accordingly. As follows:
Private void form1_paint (Object sender, painteventargs E)
...{
If (curimage! = NULL & I = 0)
...{
Graphics G = This. creategraphics ();
G. drawimage (curimage, new rectangle
(Autoscrollposition. X,
Autoscrollposition. y,
(INT) (This. clientrectangle. Width * curzoom ),
(INT) (clientrectangle. Height * curzoom )));
}
}
|
The image should have the corresponding height and width based on the amplification factor. Next, let's take a look at the event processor corresponding to the mnu200zoom menu item:
Private void mnu200_click (Object sender, system. eventargs E)
...{
If (curimage! = NULL)
...{
Curzoom = (double) 200/100;
I ++;
Invalidate ();
}
}
|
Finally, let's take a look at the event processor corresponding to the mnuthumbnail menu item:
1 private void mnuthumbnail_click (Object sender, eventargs E) 2... { 3if (curimage! = NULL) 4... { 5I ++; 6 // callback 7image. getthumbnailimageabort tncallback = 8new image. getthumbnailimageabort (tncallbackmethod); 9 // obtain the thumbnail image 10 image thumbnailimage = curimage. getthumbnailimage 11 (100,100, tncallback, intptr. zero); 12 // create a graphics object 13 graphics tmpg = this. creategraphics (); 14tmpg. clear (this. backcolor); 15 // draw a thumbnail image 16tmpg. drawimage (thumbnailimage, 10, 10, thumbnailimage. width, thumbnailimage. height); 17 // release the graphics object 18tmpg. dispose (); 19 }< br> 20 21 }< br> 22 |
Here, we first create a variable of the getthumbnailimageabort type and assign it the value tncallbackmethod ()-This is implemented by passing it to the getthumbnailimageabort method. Then, it creates an instance of the new image class to store the image returned by the getthumbnailimage method-this method will then be used to draw the thumbnail to the screen.
Iv. Summary
In this article, I only discussed some basic practical operation snippets about GDI + programming in the. NET C # environment. In the futureArticleWe will gradually discuss the advanced features of. Net GDI + programming.
[Note] ① the source code of this article has been debugged in the Windows XP unzip Sonal + vs2005 environment;
② In this example, the introduction of private variable I is only used to distinguish screen repainting from thumbnail painting. Readers can consider other clever methods;
③ Screen jitter occurs during image re-painting and scrolling. Readers can use the two Buffering Techniques for image rendering to improve the performance.