Windows screen capture methods

Source: Internet
Author: User
Address: http://www.cnblogs.com/fence/archive/2010/01/18/1651100.html
Reprinted with the original address, so that it is easy for others to read. --- Jia_zhengshen note

Introduction

Sometimes we need to Program Capture the content on the entire screen. Next I will introduce how to implement the capture. Typically, we can use GID and DirectX to complete the process. Another option is the Windows Media API. I will analyze it one by one in this article. In each method, once we save the screen content to the memory block or bitmap file defined by the program, we can further use them to generate animations and movies, for more help, see "Create a movie from hbitmap.

Screen capture using the GDI Function

If we do not care much about the efficiency of screen capture, and all we want is a screen snapshot, we can consider using the GDI method. This screen capture mechanism is based on the simple common sense that "desktop is also a window, and desktop also has a window handle (hwnd)". If we get the desktop device context (DC ), you can use bits to copy its content to the DC we created. We can use getmediawindow () to get the desktop window handle. It is also easy to get DC from the handle. The specific steps are as follows:

1. Use the getdesktopwindow () function to obtain the window handle of the desktop.

2. Use getdc () to obtain the DC of the desktop window

3. Create bitmap and DC (createcompatiblebitmap () and createcompatibledc () compatible with the screen DC, and select this bitmap to the DC (SelectObject ())

4. When you are ready to capture the screen, copy the content of the DC in the desktop window to the compatible DC, and you will complete the screen capture process. The compatible bitmap is the screen content at the time of screen capture.

5. Do not forget to release the object you created after the completion. The memory is precious (for other programs)

Sample Code:

Void capturescreen ()

{

Int nscreenwidth = getsystemmetrics (sm_cxscreen );

Int nscreenheight = getsystemmetrics (sm_cyscreen );

Hwnd hsf-topwnd = getw.topwindow ();

HDC hsf-topdc = getdc (hsf-topwnd );

HDC hcapturedc = createcompatibledc (hsf-topdc );

Hbitmap hcapturebitmap = createcompatiblebitmap (hsf-topdc,

Nscreenwidth, nscreenheight );

SelectObject (hcapturedc, hcapturebitmap );

Bitblt (hcapturedc, 0, 0, nscreenwidth, nscreenheight, hsf-topdc, 0, 0, srccopy );

Savecapturedbitmap (hcapturebitmap); // place holder-put your code

// Here to save the captured image to disk

Releasedc (hsf-topwnd, hsf-topdc );

Deletedc (hcapturedc );

Deleteobject (hcapturebitmap );

}

In the code snippet above, getsystemmetrics () returns the width (sm_cxscreen) and height (sm_cyscreen) of the screen ). For more information about how to save the captured bitmap to a file and how to set it to the clipboard, see the source code. The sample code captures the screen at intervals using the above technology and saves the image sequence to the animation

 

DirectX Mode

Screen capture with dreictx is also very simple, DirectX provides a very elegant implementation.

Each DirectX program contains a memory area called a buffer, which stores the video content related to the program, which is called a back buffer in the program ), some programs have more than one background buffer. There is also a buffer. By default, each program can access the front-end buffer. The front-end buffer saves the desktop-related video content, which is essentially a screen image.

Our program can capture the content of the current screen by accessing the front-end buffer. The underlying optimization mechanism of DirectX ensures that our screen capture efficiency is very high, at least higher than that of GDI.

It is very easy to access the front-end buffer in the DirectX program. The idirect3ddevice8 interface provides the getfrontbuffer () method, which receives an idirect3dsurface8 object pointer as a parameter and copies the content of the front-end buffer to the surface. Idirect3dsurfce8 object can be obtained using idirect3ddevice8: createimagesurface. Once the screen content is saved to this surface, we can use the d3dxsavesurfacetofile () method to directly Save the content to the disk BMP file. The sample code is as follows:

Extern idirect3ddevice8 * g_pd3ddevice;

Void capturescreen ()

{

Idirect3dsurface8 * psurface;

G_pd3ddevice-> createimagesurface (screenwidth, screenheight,

D3dfmt_a8r8g8b8, & psurface );

G_pd3ddevice-> getfrontbuffer (psurface );

D3dxsavesurfacetofile ("shorttop.bmp", d3dxiff_bmp, psurface,

Null, null );

Psurface-> release ();

}

Previously, g_pd3ddevice is an initialized idirect3ddevice object. In this example, the captured image is saved to a file. However, sometimes we want to access each bit in the image directly, we can use idirect3dsurface8: lockrect (), which gives us a pointer to execute the surface memory, that is, the captured image data. We can copy the data to the memory defined by the program to operate on it. See the following code:

Extern void * pbits;

Extern idirect3ddevice8 * g_pd3ddevice;

Idirect3dsurface8 * psurface;

G_pd3ddevice-> createimagesurface (screenwidth, screenheight,

D3dfmt_a8r8g8b8, & psurface );

G_pd3ddevice-> getfrontbuffer (psurface );

D3dlocked_rect lockedrect;

Psurface-> lockrect (& lockedrect, null,

D3dlock_no_dirty_update | d3dlock_nosyslock |

D3dlock_readonly )));

For (INT I = 0; I <screenheight; I ++)

{

Memcpy (byte *) pbits + I * screenwidth * bitsperpixel/8,

(Byte *) lockedrect. pbits + I * lockedrect. pitch,

Screenwidth * bitsperpixel/8 );

}

G_psurface-> unlockrect ();

Psurface-> release ();

The above pbits is a void *. please ensure that the Group has enough memory space for it first. Bitsperpixel generally uses a 32-bit color. It also depends on the current configuration of your monitor. Note that the surface width is different from the captured screen width. Because of memory alignment (memory alignment by word is usually at a high access validity rate), the surface may have excess bits at the end of each line to align it to the word boundary. Lockedrect. Pitch provides the number of bytes between the beginning of two consecutive rows. That is to say, when reading a row, we need to move the pointer pitch byte backward instead of the width byte. You can use the following code to copy the surface in reverse order:

For (INT I = 0; I <screenheight; I ++)

{

Memcpy (byte *) pbits + (screenheight-I-1 )*

Screenwidth * bitsperpixel/8,

(Byte *) lockedrect. pbits + I * lockedrect. pitch,

Screenwidth * bitsperpixel/8 );

}

This is useful for top-down bitmap to bottom-up bitmap.

We can also use the getdc () method of idirect3dsurface9 to obtain the GDI compatible DC of DirectX surface, and then copy its content to our compatible DC. If you are using directx9, try it.

At last, it should be noted that frontbuffer is a relatively slow operation and is designed in this way, so it should be avoided in programs with critical efficiency. You have been warned! The source code included in this article uses this technology to regularly capture the screen and save it as an animation.

 

 

 

Screen capture using Windows Media APIs

Windows Media 9.0 supports the use of the Windows Media Encoder 9 API for screen capture. It has an encoder named Windows Media video 9 screen codec, especially optimized for screen capture. The Windows Media Encoder API provides an iwmencoder2 interface to efficiently capture screen images.

It is also very easy to use this technology for screen capture. First, we use cocreateinstance () to create an iwmencoder2 object:

Iwmencoder2 * g_pencoder = NULL;

Cocreateinstance (clsid_wmencoder, null, clsctx_inproc_server,

Iid_iwmencoder2, (void **) & g_pencoder );

This encoder object contains all the operations required to capture the screen. However, to work correctly, the behavior of the encoder object depends on the settings called profile. A profile is only a file containing all the encoding control settings. We can create a profile containing custom settings at runtime Based on the captured data features. To use profile in your screen capture program, we create a custom profile based on Windows Media video 9 screen codec. The custom profile object is supported since iwmencprofile2. We can use cocreateinstance to create a custom profile.

Iwmencprofile2 * g_pprofile = NULL;

Cocreateinstance (clsid_wmencprofile2, null, clsctx_inproc_server,

Iid_iwmencprofile2, (void **) & g_pprofile );

I need to specify the audience of the encoder in the profile ). Each profile can contain multiple listener configurations, which are iwmencaudienceobj interface objects. Here we use an audience for profile. We can use iwmencprofile: addaudience () to create an audience for our profile. This function returns an iwmencaudienceobj pointer that can be used to configure the video encoder (iwmencaudienceobj: put_videocodec ()), video Frame object (iwmencaudienceobj: put_videoheight ()
And iwmencaudienceobj: put_videowidth () we use the following code to configure the Video Encoder:

Extern iwmencaudienceobj * paudience;

# Define videocodec makefourcc ('M', 's', 's', '2 ')

// Mss2 is the fourcc for the screen Codec

Long lcodecindex =-1;

G_pprofile-> getcodecindexfromfourcc (wmenc_video, videocodec,

& Lcodecindex); // get the index of the Codec

Paudience-> put_videocodec (0, lcodecindex );

Fourcc is the unique identifier for Each encoder. fourcc of Windows Media video 9 screen codec is mss2. Iwmencaudienceobj: put_videocodec () accepts the profile index to organize a profile. The index can be obtained using iwmencprofile: getcodecindexfromfourcc.

Once we have configured a profile object, we can use iwmencsourcegroup: put_profile () to select this profile to our encoder. A source group (sourcegruop) is a set of Video Stream sources, audio stream sources, or HTML sources. Each encoder can use many source groups and obtain input data from them. Because our program only uses video streams as the video source. This video source needs to be configured as the input source using iwmencvideosource2: setinput (BSTR) screen device:

Extern iwmencvideosource2 * psrcvid;

Psrcvid-> setinput (ccombstr ("screencap: // screencapture1 ");

You can use iwmencfile: put_localfilename () to save the output to a video file (WMV file ). The iwmencfile object can be obtained using iwmencoder: get_file:

Iwmencfile * poutfile = NULL;

G_pencoder-> get_file (& poutfile );

Poutfile-> put_localfilename (ccombstr (szoutputfilename );

Now, once all the configurations of the encoder object are complete, we can use iwmencoder: Start () to capture the screen. Iwmencoder: Stop () and iwmencoder: pause can be used to stop and pause capture.

These are suitable for full-screen capturing. You can also select a region by adjusting the attributes of the input video to capture the source streams. We can use the ipropertybag interface of iwmenvideosource2 to implement:

# Define wmscrncap_windowleft ccombstr ("Left ")

# Define wmscrncap_windowtop ccombstr ("TOP ")

# Define wmscrncap_windowright ccombstr ("right ")

# Define wmscrncap_windowbottom ccombstr ("bottom ")

# Define wmscrncap_flashrect ccombstr ("flashrect ")

# Define wmscrncap_entirescreen ccombstr ("screen ")

# Define wmscrncap_windowtitle ccombstr ("windowtitle ")

Extern iwmencvideosource2 * psrcvid;

Int nleft, nright, ntop, nbottom;

Psrcvid-> QueryInterface (iid_ipropertybag, (void **) & ppropertybag );

Ccomvariant varvalue = false;

Ppropertybag-> write (wmscrncap_entirescreen, & varvalue );

Varvalue = nleft;

Ppropertybag-> write (wmscrncap_windowleft, & varvalue );

Varvalue = nright;

Ppropertybag-> write (wmscrncap_windowright, & varvalue );

Varvalue = ntop;

Ppropertybag-> write (wmscrncap_windowtop, & varvalue );

Varvalue = nbottom;

Ppropertybag-> write (wmscrncap_windowbottom, & varvalue );

The source code included in this article implements the technical screen capture. Apart from the quality of the generated animation, it is interesting that the mouse pointer is also captured (by default, the mouse pointer is not captured by GDI and DirectX ).

Note: To apply the windowmedia9.0 API, you must install the Windows media9.0 SDK on your computer. You can download it at the following address:

Http://msdn.microsoft.com/library/default.asp? Url =/downloads/LIST/winmedia. asp

The end user must install the Windows Media Encoder 9 Series to run your program. When you release a program based on the Windows Media Encoder SDK, the Windows Media Encoder software must also be included, either automatically installing Windows Media Encoder during your software installation or letting users download and install it by themselves.

Windows encoder 9.0 can be downloaded from the following address:

Http://www.microsoft.com/windows/windowsmedia/ 9 series/encoder/default. aspx

Conclusion

The methods discussed above are based on a single goal-capturing screen content. However, different technologies have different results. If we only need occasional screen capture, the GDI method is a good choice because it is simple. However, if you want more professional results, you can use Windows Media. One of the key points that may be meaningless is that the quality of the content captured by these technologies depends largely on your system settings, for example, hardware acceleration greatly improves the quality of screen capture and the running efficiency of programs.

 

Doodle Interactive VisualWebsites are websites that exchange and learn technologies such as multi-touch, virtual reality, augmented reality, and large screen projection display.

Duot interactive visual http://www.duduvision.com

Doodle interactive visual Forum http://forum.duduvison.com.

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.