Cimage for GDI + programming based on VC. net

Source: Internet
Author: User
Tags transparent image

We know that the cbitmap class of Visual C ++ and static image controls have weak functions. They can only display icons, bitmaps, cursors, and metadata files in resources, unlike the image control in VB, the vast majority of external image files (BMP, GIF, JPEG, etc.) can be displayed ). Therefore, to display an external image file in a dialog box or other window, you can only use the control or code provided by a third party. Now, the new class cimage shared by MFC and ATL provides many corresponding methods for image processing, which makes the image defects of Visual C ++ gone forever.

  Cimage class overview

Cimage is a new class shared by MFC and ATL. It can be transferred from an external disk to an image file in JPEG, GIF, BMP, and PNG formats for display, and these file formats can be converted to each other. Because cimage has different performance in different Windows operating systems, pay special attention to it during use. For example, cimage: plgblt and cimage: maskblt can only be used in Windows NT 4.0 or later versions, but cannot run in Windows 95/98 applications. Cimage: alphablend and cimage: transparentblt can only be used in Windows 2000/98 or later versions. Even if you are running a program in Windows 2000, you must change the prefix of winver and _ win32_winnt in the stdafx. h file to 0x0500 for normal use.

Cimage encapsulates the Dib (device-independent Bitmap) function, so that we can process each bitmap pixel. It has the following cool features:

1. alphablend supports pixel-level color mixing to achieve transparent and translucent effects.

2. plgblt can map bitmaps in a rectangle area to a parallelogram area, and may also be used for bit shielding.

3. transparentblt generates a transparent image in the target region. settransparentcolor is used to set a color to transparent.

4. maskblt generates a source bitmap and a shielded bitmap synthesis effect in the target region.

  Common cimage Method

The general method of using cimage is as follows:

(1) Open the stdafx. h file of the application and add a file containing the cimage class:

# Include <atlimage. h>

(2) define a cimage Class Object and call the cimage: Load Method to load an external image file.

(3) Call the cimage: Draw method to draw an image. The draw method has the following definitions:

 

Bool draw (HDC hdestdc, int xdest, int ydest,
Int ndestwidth, int ndestheight, int xsrc, int ysrc,
Int nscwidth, int nscheight );
Bool draw (HDC hdestdc, const rect & rectdest, const rect & rectsrc );
Bool draw (HDC hdestdc, int xdest, int ydest );
Bool draw (HDC hdestdc, const point & pointdest );
Bool draw (HDC hdestdc, int xdest, int ydest,
Int ndestwidth, int ndestheight );
Bool draw (HDC hdestdc, const rect & rectdest );

 

Hdestdc is used to specify the environment handle of the drawn target device. (xdest, ydest) and pointdest are used to specify the position where the image is displayed. The position corresponds to the position in the upper left corner of the source image. Ndestwidth and ndestheight respectively specify the height and width of the image to be displayed. xsrc, ysrc, nscwidth, and nscheight are used to specify the position and size of a part of the source image to be displayed. Rectdest and rectsrc are used to specify the location and size of a part to be displayed on the target device environment and source image respectively.

It should be noted that the draw method integrates the functions of the stretchblt, transparentblt, and alphablend functions. By default, draw has the same function as stretchblt. However, when an image contains a transparent or alpha channel, it functions the same as transparentblt and alphablend. Therefore, in general, we should try to call the cimage: Draw method to draw images.

For example, the following example uses ex_image to enable this function: When you select the "file" external "open" menu command, a file open dialog box is displayed. After an image file is selected, the image file content is displayed in the customer area of the window. The steps for this example are as follows:

(1) create a default single-document program project ex_image.

(2) Open the stdafx. h file and add the file atlimage. H of the cimage class.

(3) Add the command event ing program id_file_open in the cex_imageview class and add the following code:

 

Void cex_imageview: onfileopen ()
{
Cstring strfilter;
Csimplearray <guid> aguidfiletypes;
Hresult;

// Obtain the filter string of the image files supported by cimage
Hresult = m_image.getexporterfilterstring (strfilter, aguidfiletypes,
_ T ("all image files "));
If (failed (hresult )){
MessageBox ("getexporterfilter call failed! ");
Return;
}
Cfiledialog DLG (true, null, null, ofn_filemustexist, strfilter );
If (idok! = DLG. domodal ())
Return;

M_image.destroy ();
// Load the external image file to the cimage object
Hresult = m_image.load (DLG. getfilename ());
If (failed (hresult )){
MessageBox ("An error occurred while calling the image file! ");
Return;
}

// Set the title bar of the Main Window
Cstring STR;
Str. loadstring (afx_ids_app_title );
Afxgetmainwnd ()-> setwindowtext (STR + "-" + DLG. getfilename ());

Invalidate (); // force call ondraw
}

 

(4) locate the cex_imageview: ondraw function and add the following code:

 

Void cex_imageview: ondraw (CDC * PDC)
{
Cex_imagedoc * pdoc = getdocument ();
Assert_valid (pdoc );
If (! M_image.isnull ()){
M_image.draw (PDC-> m_hdc, 0, 0 );
}
}

 

(5) Open the ex_imageview.h file and add a Public Member Data m_image:

 

Public:
Cimage m_image;

 

(6) Compile and run. Click the open tool button. In the displayed dialog box, specify an image file and click open. Expected result 7.21 is displayed.

  Save images in other formats

Cimage: The save method can save an image file in another format. Its prototype is as follows:

Hresult save (lpctstr pszfilename, refguid guidfiletype = guid_null );

Pszfilename is used to specify a file name, And guidfiletype is used to specify the format of the image file to be saved. When guid_null is used, the file format is determined by the file extension, which is also the default value of this function. It can also be guid_bmp file (BMP file format), guid_pngfile (PNG file format), guid_1_file (JPEG file format), and guid_giffile (GIF file format ).

For example, the following process is based on the ex_image example. In the cex_imageview class, we add the id_file_save_as command event ing program and add the following code:

Void cex_imageview: onfilesaveas ()
{
If (m_image.isnull ()){
MessageBox ("You have not opened an image file to save! ");
Return;
}

Cstring strfilter;
Strfilter = "bitmap file | *. BMP | JPEG image file | *. jpg | \
GIF image file | *. gif | PNG Image File | *. PNG | ";
Cfiledialog DLG (false, null, strfilter );
If (idok! = DLG. domodal ())
Return;

// If the user does not specify the file extension, add
Cstring strfilename;
Cstring strextension;

Strfilename = DLG. m_ofn.lpstrfile;
If (DLG. m_ofn.nfileextension = 0)
{
Switch (DLG. m_ofn.nfilterindex)
{
Case 1:
Strextension = "BMP"; break;
Case 2:
Strextension = "jpg"; break;
Case 3:
Strextension = "GIF"; break;
Case 4:
Strextension = "PNG"; break;
Default:
Break;
}
Strfilename = strfilename + '.' + strextension;
}

// Save the image
Hresult = m_image.save (strfilename );
If (failed (hresult ))
MessageBox ("An error occurred while saving the image file! ");
}

 

  Softening and sharpening

In image processing, we usually use some mathematical methods to transform the image space, such as removing noise, emphasizing or extracting contour features. The so-called "image space transformation" is implemented by a local pixel domain called a template. Different templates have different image effects.

1. softening

Image softening is an effective method to remove the point noise in the image. The so-called softening means that the color value of any pixel on the image and its adjacent pixels will not be steep. In a 3x3 template, the coefficient is:

It indicates the central element with a shading in the middle, that is, the processed element. Obviously, the above template (called the box template) replaces each pixel on the image with the average value of nine pixels next to it (including itself. In addition to noise, the processing results also reduce the contrast of the image and blur the contour of the image. To avoid this defect, we introduce the weighting coefficient to each point and change the original template:

The new template can remove the point noise and retain the contrast of the original image. Therefore, this template is widely used. This template is called a Gaussian template because it is obtained through the two-dimensional Gaussian (Gauss) function.

2. Sharpen

Sharpening and softening are just the opposite. It reduces the Blur in the image by enhancing the high-frequency components, and is also called high-pass filtering. Sharpening enhances the image edge effect while increasing the image noise. The common sharpen template is the Laplace template:

After the image is processed using this template, the contour lines will be significantly enhanced. Parts outside the contour line will become darker, and the contour line part will become brighter.

When you use a program to perform operations on the template, consider the overflow. Overflow refers to a point greater than 255 or less than 0. During Processing, 255 can be set for vertices greater than 255, while for vertices smaller than 0, the positive value can be obtained.

3. Implementation Code

For softening and sharpening, we first call cimage: getpixel to read the corresponding pixels in sequence, then use the softening and sharpening templates for processing, and finally call cimage :: the setpixel function writes the processed pixels back to the cimage object. The specific code is as follows:

 

Void filterimage (cimage * image, int ntype)
{
If (image-> isnull ())
Return;
Int smoothgauss [9] = {, 1}; // Gaussian Template
Int sharplaplacian [9] = {-1,-1,-1,-,-1,-1,-1,-1}; // Laplace Template

Int optemp [9];
Float aver; // Coefficient
If (ntype> 1) ntype = 0;
Switch (ntype ){
Case 0: // Gaussian Template
Aver = (float) (1.0/16.0 );
Memcpy (optemp, smoothgauss, 9 * sizeof (INT ));
Break;
Case 1: // Laplace Template
Aver = 1.0;
Memcpy (optemp, sharplaplacian, 9 * sizeof (INT ));
Break;
}

Int I, J;

Int nwidth = image-> getwidth ();
Int nheight = image-> getheight ();

For (I = 1; I <nWidth-1; I ++ ){
For (j = 1; j <nHeight-1; j ++ ){

Int RR = 0, GG = 0, BB = 0;
Int Index = 0;

For (INT Col =-1; Col <= 1; Col ++ ){
For (int row =-1; row <= 1; row ++ ){
Colorref CLR = image-> getpixel (I + row, J + col );
RR + = getrvalue (CLR) * optemp [Index];
Gg + = getgvalue (CLR) * optemp [Index];
BB + = getbvalue (CLR) * optemp [Index];
Index ++;
}
}
  
RR = (INT) (RR * aver );
Gg = (INT) (Gg * aver );
BB = (INT) (bb * aver );

// Handle overflow
If (RR> 255) RR = 255;
Else if (RR <0) RR =-RR;
If (Gg> 255) Gg = 255;
Else if (Gg <0) Gg =-GG;
If (BB> 255) BB = 255;
Else if (BB <0) BB =-BB;

// Misaligned rewrite to prevent the previous pixel from being overwritten by the new Pixel
Image-> setpixel (I-1, J-1, RGB (RR, GG, BB ));
}
}
}

 

Figure 7.22 is the result of processing an image using the above Code.

  Black/white image

Because many image files use a color table to display the color of the display device, you need to call cimage: isindexed to determine whether to use a color table when turning a color image into a black image, if yes, modify the color table. Otherwise, set the color of the pixel directly. For example, the following code:

Void cex_imageview: makeblackandwhite (cimage * image)
{
If (image-> isnull () return;

If (! Image-> isindexed ()){
// Directly modify the pixel color
Colorref pixel;
Int Maxy = image-> getheight (), Maxx = image-> getwidth ();
Byte R, G, B, AVG;
For (INT x = 0; x <Maxx; X ++ ){
For (INT y = 0; y <Maxy; y ++ ){
Pixel = image-> getpixel (x, y );
R = getrvalue (pixel );
G = getgvalue (pixel );
B = getbvalue (pixel );
AVG = (INT) (R + G + B)/3 );
Image-> setpixelrgb (X, Y, AVG, AVG, avg );
}
}
} Else {
// Obtain and modify the color table
Int maxcolors = image-> getmaxcolortableentries ();
Rgbquad * colortable;
Colortable = new rgbquad [maxcolors];
Image-> getcolortable (0, maxcolors, colortable );
For (INT I = 0; I <maxcolors; I ++)
{
Int AVG = (colortable [I]. rgbblue + colortable [I]. rgbgreen + colortable [I]. rgbred)/3;
Colortable [I]. rgbblue = AVG;
Colortable [I]. rgbgreen = AVG;
Colortable [I]. rgbred = AVG;
}
Image-> setcolortable (0, maxcolors, colortable );
Delete (colortable );
}
}

So far, we have introduced the general usage methods and techniques of GDI + and cimage. Of course, they also have many more in-depth methods. Due to space limitations, we will not discuss them here.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.