Implementation of image cutting using direct technology

Source: Internet
Author: User
Tags transparent color transparent image
Xuyan:
This is a superficial article. Strictly speaking, it is not a technical article. It can only be said that it is a bit of your own experience in learning direct programming, however, it still contains a lot of basic knowledge about Win32 programming and direct programming. Here, we are looking to make a little effort for our friends who are engaged in direct programming, this article focuses on the process of using direct programming to reduce an image, as shown below:
  
Before cutting:
    
After reduction:
    
The place where the white line is drawn in the figure is the area ^_^ after the cut.
If your friends find bugs in them, please let me know. If you have any better comments and suggestions, please tell me ^_^.
  
   First: first glance
Windows Programming involves a certain process. In fact, we must first create a primary function, which should be a large message loop, the general process of this main function is as follows:
    
First, we must create a form and register it. Then we can do more based on the form, just like having a canvas first, then we can draw in the canvas.
  
//************************************** **********************
// Function: winmain ()
// Function: Windows program entry function. Create a main window to process message Loops
//************************************** **********************
Int Pascal winmain (hinstance, hinstance hprevinstance, lpstr lpcmdline, int ncmdshow)
{
MSG; // message structure
  
Initwindow (hinstance, ncmdshow); // initialize the form
  
While (1) // message loop
{
If (peekmessage (& MSG, null, 0, 0, pm_remove ))
{
If (msg. Message = wm_quit) // exit the message loop
Break;
Translatemessage (& MSG); // gets the message and processes the callback function.
Dispatchmessage (& MSG );
}
}
Return msg. wparam;
}
  
Before talking about the message loop of this program, I 'd like to talk about the differences between DOS and Windows Driver mechanisms:
  
DOS programs mainly use sequential and process-driven programming methods. In order, the process-driven program has a clear start, a clear process and a clear end, so the program can directly control the program event or the order of the process. Although there are many Exception Handling Methods in the sequential process-driven program, such exception handling is still sequential and process-driven structure.
  
Windows drivers are event-driven, that is, they are not controlled by the order of events, but controlled by the occurrence of events. All events are unordered and act as a programmer, when you write a program, you do not know which button the user presses first, or which message the program triggers first. Your task is to sort and manage the messages to be sent or received by developing applications. The event driver is designed to closely focus on the generation and processing of messages. A message is a message about an event.
  
  
The prototype of the winmain () function is as follows:
  
Int Pascal winmain (hinstance, hinstance hprevinstance, lpstr lpcmdline, int ncmdshow)
  
The first hinstance parameter is the handle that identifies the application. But what is the handle? It is actually a pointer to the memory area occupied by the program. It uniquely represents the application, and Windows uses it to manage various objects in the memory.
The second parameter is hprevinstance. Leave it alone as the handle of the previous instance of the application. For Win32 bits, it is generally null.
The third parameter is the lpcmdline, which is a pointer to the application command line parameter string. For example, if we run "test hello", the string to which this parameter points is "hello ".
The last parameter is ncmdshow, which is an integer used to specify the window display mode. It tells the application how to initialize the window, such as maximizing or minimizing the status. Other types of window display methods are described.
    
Then we need to initialize the form and register it before we can use it.
//************************************** **********************
// Function: initwindow ()
// Function: create a window
//************************************** **********************
Static bool initwindow (hinstance, int ncmdshow)
{
Wndclass WC;
WC. Style = NULL; // window style
WC. lpfnwndproc = (wndproc) winproc; // pointer to the window procedure Function
WC. cbclsextra = 0; // additional window data
WC. cbwndextra = 0; // additional window data
WC. hinstance = hinstance; // instance handle with window class
WC. hicon = NULL; // minimum window icon
WC. hcursor = NULL; // cursor used in the window
WC. hbrbackground = NULL; // The brush used to color the window background
WC. lpszmenuname = NULL; // pointer to the menu Resource Name
WC. lpszclassname = "menpao_rpg_demo"; // pointer to the window class name
Registerclass (& WC); // registration window
Hwnd = createwindow ("temperature", "temperature", ws_popup | ws_maximize, 0, getsystemmetrics (sm_cxscreen), getsystemmetrics (sm_cyscreen), null, null, hinstance, null );
If (! Hwnd) return false;
Showwindow (hwnd, ncmdshow); // display window
Updatewindow (hwnd); // refresh the window
Return true;
}
(1) The first parameter: The member style controls some important features of the window style, in windows. h defines some constants prefixed with Cs, which can be combined in the program. other features include:
    
(2) The second parameter: lpfnwndproc. Just give it the function name of the message processing function. If necessary, force type conversion should be performed to convert it to the wndproc type.
(3) third, four parameters: the cbwndextra field specifies the number of extra bytes allocated for all window structures created using this window class. When more than two windows belong to the same window class, if you want to correspond different data to each window. This domain is useful. In this case, you only need to set them to 0, so you don't have to worry too much.
(4) Fifth parameter: hinstance member. The value is the handle of the application corresponding to the window, indicating that the window is associated with this application.
(5) Sixth parameter: The member hicon is set to the handle of the icon used by the application. The icon is the icon that appears in the taskbar when the application is minimized, it indicates that the program is still resident in the memory. Windows provides some default icons. You can also define your own icons. A dedicated icon creation tool is provided in VC.
(6) Seventh parameter: The hcursor field defines the shape of the cursor generated by the window. Loadcursor can return the inherent cursor handle or the cursor handle defined by the application. Idc_arrow indicates the arrow cursor.
(7) parameter 8: The hbrbackground member is used to define the background color of the window. Set this parameter to null.
(8) Ninth parameter: lpszmenuname is used to specify the menu name. The menu is not defined in this program, so it is null.
(9) Tenth parameter: lpszclassname specifies the class name in this window. This program is named "menpao_rpg_demo ".
After assigning values to the wndclass structure fields, you can register the window class. Before creating the window, you must register the window class. The Registry window class uses the registerclass API function, if the registration fails, a dialog box is displayed, as shown in the program. The registerclass function returns a value of 0 and only a value of 0. Because the registration fails, the program can no longer proceed.
  
After registration, this form is created. Generally, the creatwindows () function in the API function is called at the moment.
The preceding registration form is used as an example.
Hwnd = createwindow (
"Menpao_rpg_demo", // name of the created form class
"Menpao_rpg_demo", // window title
Ws_popup | ws_maximize, // window style. For all the styles, see the following table.
0, // X coordinate of the window position
0, // y coordinate of window position
Getsystemmetrics (sm_cxscreen), // window height, full screen
Getsystemmetrics (sm_cyscreen), // window height, full screen
Null, // parent window handle
Null, // menu handle
Hinstance, // application handle
Null); // The last parameter is additional data, usually 0
Parameter 1: the name of the registered window class. This class name has been defined in the registration window just now.
Parameter 2: used to indicate the title of the window. It can be the same as the first parameter.
Parameter 3: used to indicate the window style, such as whether to maximize or minimize the button. For details about other styles, see
    
In DirectX programming, we generally use ws_popup | ws_maximize. The window created with this sign has no title bar and System menu, and the window is maximized, which can fully meet the needs of DirectX programming.
  
Parameter 4, 5 indicates the coordinates of the window on the screen after the program runs.
6, 7 indicates the size of the window (namely, the length and width) at the time of window initialization (that is, when the program is initially running.
Parameter 8: You can specify the parent window when creating a window. If there is no parent window, the parameter value is 0.
Parameter 9: used to specify the menu of the window. The menu will be described later. The value is 0 currently.
The last parameter is additional data, usually 0.
If the window is created successfully, createwindow () returns the handle of the new window. Otherwise, null is returned.
You must call another API function to see that the form is showwindow. Its prototype is:
Showwindow (hwnd, icmdshow)
The first parameter is the window handle, which tells showwindow () the window to display, while the second parameter tells it how to display the window, there are many other styles.
    

After winmain () calls showwindow, you also need to call the updatewindow function to display the window. Call the updatewin function.

OK, and then set the display mode function. Its prototype is:
Hresult setdisplaymode (
DWORD dwwidth,
DWORD dwheight,
DWORD dwbpp,
DWORD dwrefreshrate,
DWORD dwflags
);
  
Dwwidth and dwheight are used to set the width and height of the display mode.
Dwbpp is used to set the color digits of the display mode.
Dwrefreshrate sets the screen update rate. 0 indicates the default value.
The only valid value of dwflags is ddsdm_standardvgamode.
  
Create a page, clear it first, and apply for a space (similar to the destructor in C)
  
Memset (& ddsd, 0, sizeof (ddsurfacedesc2); // start to create the home page, first clear the page description
Ddsd. dwsize = sizeof (ddsd); // fill in the page description
Ddsd. dwflags = ddsd_caps | ddsd_backbuffercount; // There is a background Cache
Ddsd. ddscaps. dwcaps = ddscaps_primarysurface | ddscaps_flip | ddscaps_complex;
Ddsd. dwbackbuffercount = 1; // a background Cache
Lpdd-> createsurface (& ddsd, & lpddsprimary, null); // create a home page
  
Create a function prototype on the home page:
  
Hresult createsurface (
Lpddsurfacedesc2 lpddsurfacedesc,
Lpdirectdrawsurface far * lplpddsurface,
Iunknown far * punkouter
);
  
The first parameter is the address of the ddsurfacedesc2 structure filled with page information. Here it is & ddsd;
The second parameter is the address for receiving the Home Page pointer, Which is & lpddsprimary;
The third parameter must be null, which is reserved by the function.
  
Creating a page with the background and mouse is also a truth.
The next part is the texture. paste the image to be displayed first, and specify its position for a pointer. You can directly operate the pointer when using it later. However, we still need to clear the page before, and set the transparent color of the image after the image is pasted, so that the image can be seen.
  
// Clear all pages
Ddbltfx;
Ddbltfx. dwsize = sizeof (ddbltfx );
Ddbltfx. dwfillcolor = 0;
Lpddsprimary-> BLT (null, ddblt_wait | ddblt_colorfill, & ddbltfx );
Lpddsbuffer-> BLT (null, ddblt_wait | ddblt_colorfill, & ddbltfx );
Lpddsmap-> BLT (null, ddblt_wait | ddblt_colorfill, & ddbltfx );
Lpddsmouse-> BLT (null, ddblt_wait | ddblt_colorfill, & ddbltfx );
  
// Map and set transparent colors
Ddreloadbitmap (lpddsmap, "inn. BMP ");
Ddreloadbitmap (lpddsmouse, "Mouse. BMP ");
Makerect (0, 0, 640,480 );
Lpddsprimary-> bltfast (0, 0, lpddsmap, & R, nokey );
Ddsetcolorkey (lpddsmap, RGB (0,255, 0 ));
Ddsetcolorkey (lpddsmouse, RGB (0,255, 0 ));
  
It's time to take a rest.
Reader: "Why is this person so irresponsible? I always write it without head or tail! # $ % * ^ *"
Weter: "Let's sell a token first. In the next chapter, we will go to the implementation of specific functions. How did we complete the image cutting? How does it work ?"
Wait for the next decomposition.
  
  Forth:
Today is the last one, and we haven't gotten into the topic for so long. I can't help you anymore. Today we are going to enter the core of this lengthy story, it is also the last part.
  
In direct programming, there are two important functions that are frequently used. before entering the topic, we must first introduce these two functions, they are also used in our program.
  
The first useful function is bltfast (). Its prototype is
Hresult bltfast (
DWORD dwx,
DWORD dwy,
Lpdirectdrawsurface lpddsrcsurface,
Lprect lpsrcrect,
DWORD dwtrans
);
  
The following describes these parameters one by one:
(1) dwx and dwy: where the image will be transmitted to the target page.
(2) lpddsrcsurface: image transfer operation Source Page. The target page is the page that calls this method.
(3) lpsrcrect: the address of a rect (rectangle) structure, indicating the area to be transmitted on the Source Page. If this parameter is null, the entire source page will be used. Rect structure is very common in DirectDraw. It is best to define a global variable of the rect type in the program, such as rect, and then write a function like this: void makerect () (This function is the second very useful function I have mentioned. We will introduce it and describe it later ).
(4) dwtrans: Specifies the transfer type. There are several types:
Ddbltfast_nocolorkey
Specifies a normal copy without transparent components.
Ddbltfast_srccolorkey
Specify a transparent image transfer to use the transparent color of the Source Page.
Ddbltfast_wait
If the image transmitter is busy, retry until the image transmitter is ready and delivered. This parameter is generally used. Because the fourth parameter is long and sometimes used together, two global variables are defined most of the time, which is more convenient to use later.
DWORD srckey = ddbltfast_srccolorkey | ddbltfast_wait
DWORD nokey = ddbltfast_nocolorkey | ddbltfast_wait
The second useful function is the void makerect () We mentioned earlier. This is generally a user-defined function. We can define it like this:
  
Void makerect (INT left, int top, int right, int bottom)
{
Rect. Bottom = bottom;
Rect. Left = left;
Rect. Right = right;
Rect. Top = top;
}
  
It mainly determines the four edges of the r structure.
So it's easy to cut an image to a page, isn't it ^ _ ^? For example: Which background should we post to the sprimary homepage, you can.
Makerect (0, 0, 640,480 );
Lpddsbuffer-> bltfast (0, 0, lpddsprimary, & R, nokey );
  
  
Core
  
Because the background size is 640*480, our right margin is 640, and the bottom margin is 480. Finally, we can use the bltfast () function to paste it out without transparency, in this way, we can map the image.
  
But how can we cut it? In fact, there is no difficulty. You want to change the size of the texture in the makerect () function. Can you paste the image part at any position in the same region, this is to cut the plug, and then we set it to a variable, and use the mouse to customize the size of the paste, it must be combined with the Windows message loop mechanism to use the plug, when mousedown, we get a coordinate of him. When mouseup, we get another coordinate of him. Then we can paste the picture between the two coordinates. In fact, the main core technology of this program is here, and the idea of implementation is also the case. Easy to use :). Other things are nothing else. But we still need to finish the introduction.
  
OK. Here we can write a class to complete our image cutting and texture functions. We will write a class called draw. CPP. Here we also set the header file draw. h.
  
Draw. h:
# If! Defined (draw_h)
# Define draw_h
  
Class draw
{
Public:
Int x1;
Int Y1;
Int X2;
Int Y2;
Void rectanglep (INT X1, int Y1, int width, int height); // you can call this function to move a rectangle over the screen.
Void BLT (INT X1, int Y1, int X2, int Y2); // completes the image cropping function.
};
  
# Endif
  
Draw. cpp:
# Include "Main. H"
  
Void draw: BLT (INT X1, int Y1, int X2, int Y2)
{
X1 = drawp. x1;
Y2 = drawp. Y1;
X2 = drawp. X2;
Y2 = drawp. Y2;
Makerect (x1, Y1, X2, Y2 );
Lpddsbuffer-> bltfast (0, 0, lpddsmap, & R, srckey );
}
  
Void draw: rectanglep (INT X1, int Y1, int X2, int Y2)
{
HDC;
Lpddsprimary-> getdc (& HDC); // get the handle on the home page
Hpen red_pen = createpen (ps_solid, 0, RGB (0,255, 0); // fill the color of the paint brush
SelectObject (HDC, red_pen); // you can specify the paint brush type.
Line (x1, Y1, X1, Y2, HDC); // draw a line
Line (x1, Y1, X2, Y1, HDC );
Line (X2, Y1, X2, Y2, HDC );
Line (x1, Y2, X2, Y2, HDC );
Lpddsprimary-> releasedc (HDC); // release the handle after use
}
  
Here is the embodiment of the two udfs.
The first function is the section we introduced earlier to reduce the image, and defines four variables as the coordinates of the mouse points.
The second function is the trajectory drawn by moving the mouse on the screen. It is a rectangle composed of four lines. Here we use the API function to plot, that is, the functions that Microsoft has given us (Microsoft has encapsulated everything for us and it is really convenient to use it ).
  
Then there is a class of common functions. All the custom functions can be used freely.
We define it
  
Publicfuction. cpp
  
// Initialization of direct. As described earlier, see the previous chapter.
Void Init ()
{
Ddsurfacedesc2 ddsd;
Directdrawcreateex (null, (void **) & lpdd, iid_idirectdraw7, null );
Lpdd-> setcooperativelevel (hwnd, ddscl_exclusive | ddscl_fullscreen );
Lpdd-> setdisplaymode (640,480, 32, 0, ddsdm_standardvgamode );
Memset (& ddsd, 0, sizeof (ddsurfacedesc2 ));
Ddsd. dwsize = sizeof (ddsd );
Ddsd. dwflags = ddsd_caps | ddsd_backbuffercount;
Ddsd. ddscaps. dwcaps = ddscaps_primarysurface | ddscaps_flip | ddscaps_complex;
Ddsd. dwbackbuffercount = 1;
Lpdd-> createsurface (& ddsd, & lpddsprimary, null );
  
Ddsd. ddscaps. dwcaps = ddscaps_backbuffer;
Lpddsprimary-> getattachedsurface (& ddsd. ddscaps, & lpddsbuffer );
  
Ddsd. dwsize = sizeof (ddsd );
Ddsd. dwflags = ddsd_caps | ddsd_width | D

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.