The original: C # WPF uses the screenshot key to achieve the screenshot function
? ? Recently do a WPF program needs to function, find the data cost some twists and turns, share with you.
???? First, we found a code like this:
???? static? class? Screencut
???? {
???????? public? static? System.Drawing. Bitmap? Getscreensnapshot ()
???????? {
???????????? System.Drawing. Rectanglerc = System.Windows.Forms. systeminformation. Virtualscreen;
???????????? System.Drawing. Bitmap? Bitmap =new? System.Drawing. Bitmap (RC. Width, RC. Height, System.Drawing.Imaging. PixelFormat. FORMAT32BPPARGB);
???????????? using? (System.Drawing. Graphics? g = System.Drawing. Graphics. FromImage (bitmap))
???????????? {
???????????????? G.copyfromscreen (RC. X, RC. Y, 0, 0, RC. Size, System.Drawing. copypixeloperation. SourceCopy);
????????????}
???????????? returnbitmap;
????????}
???????? public? static? BitmapSource? Tobitmapsource (this?) System.Drawing. BitmapBMP)
???????? {
???????????? bitmapsource? Returnsource;
???????????? Try
???????????? {
???????????????? Returnsource = System.Windows.Interop. Imaging. Createbitmapsourcefromhbitmap (BMP. Gethbitmap (),IntPtr. Zero, int32rect. Empty, bitmapsizeoptions. Fromemptyoptions ());
????????????}
???????????? Catch
???????????? {
???????????????? Returnsource = null;
????????????}
???????????? returnReturnsource;
????????}
?
???????? public? static? BitmapSource? Copyfromscreensnapshot (bitmapsourcescreensnapshot,Rect. Region)
???????? {
???????????? var? sourcerect = new? System.Drawing. Rectangle (int) region. Left, (int.) region. Top, (int) region. Width, (int) region. Height);
???????????? var? destrect = new? System.Drawing. Rectangle (0, 0, sourcerect.width, sourcerect.height);
?
???????????? if? (Screensnapshot! = null)
???????????? {
???????????????? var? bitmap = new? System.Drawing. Bitmap (Sourcerect.width, Sourcerect.height, System.Drawing.Imaging. PixelFormat. FORMAT32BPPARGB);
???????????????? using? (System.Drawing. Graphics? g = System.Drawing. Graphics. FromImage (bitmap))
???????????????? {
???????????????????? G.drawimage (Bitmap, Destrect, Sourcerect.left, Sourcerect.top, Sourcerect.width, Sourcerect.height, System.Drawing. GraphicsUnit. Pixel);
????????????????}
?
???????????????? returnbitmap. Tobitmapsource ();
????????????}
?
???????????? return? null;
????????}
}
?
When the call is wrapped, the following function truncates the screen and saves the specified area:
???? System.Drawing. Imagetakepicture (Rectwnd,string? savelocation, string? picturename)
{ ???
???????? bitmapsource? bitmapscr = screencut. Copyfromscreensnapshot (screencut. Tobitmapsource (screencut. Getscreensnapshot ()), WND);
???????? pngbitmapencoder? encoder = new? Pngbitmapencoder ();
???????? Encoder. Frames.add (bitmapframe. Create (BITMAPSCR));
???????? FileStream? FileStream = new? FileStream (SaveLocation + "\"? + picturename ". png", FileMode. Create, fileaccess. Write);
???????? Encoder. Save (FileStream);
???????? Filestream.close ();
}
?
But the actual effect saved by the diagram is empty, the first two functions verified no problem. So I looked up the data and found another way to cut bitmapsource , changing the third function to this:
BitmapSource? Copyfromscreensnapshot (bitmapsourcescreensnapshot,Rect. Region)
{
???????? int32rectwindow?= new int32rect(region. X, Region. Y, Region. Width, Region. Height);
???????? bitmapsource? bitmapscr =screencut. Tobitmapsource (screencut. Getscreensnapshot ());
???????? //Calculation Stride
???????? int? stride = bitmapScr.Format.BitsPerPixel * window. WIDTH/8;
???????? //Declare byte array
???????? byte [] data = new? byte [Window. Height * Stride];
???????? //Call CopyPixels
???????? Bitmapscr.copypixels (window, data, stride, 0);
???????? pngbitmapencoder? encoder = new? Pngbitmapencoder ();
???? return? BitmapSource. Create (window. Width, window. Height, 0, 0,pixelformats. Bgr32, null, data, stride);
}
?
This will finally be able to intercept the screen. However, it was later found that some of the program's windows were transparent in the truncated image under certain topics. This method is still not perfect.
I think of the way to use the screen key of the keyboard and then cut. Divided into three steps: 1, Analog Press the screenshot key 2, from the Clipboard to get the picture 3, capture and save the picture.
For 1th, it's no use using the SendMessage function to send the Wm_key event, but I found another way to simulate keyboard input:
using? System.Runtime.InteropServices;
???? [DllImport("user32.dll")]
???? static? extern? void? keybd_event
???? (
???????? bytebvk,//virtual key value
???????? bytebscan,//Hardware scan code???
???????? uintdwFlags,//action ID???
???????? IntPtr? dwExtraInfo//supplementary information associated with the keyboard action???
);
?
Above this function to send button events to this program, analog screenshot key words like the following write, WPF needs to add a reference to the project System.Windows.Forms
Const? int? Vk_snapshot = 0x2C;
???? public? void? Printscreen ()
???? {
???????? Keybd_event ((byte) vk_snapshot, 0, 0x0,IntPtr. Zero); //down?
???????? System.Windows.Forms. application. DoEvents (); // Force Window Response button Event
???????? keybd_event (byte) vk_snapshot, 0, 0x2,IntPtr. Zero); //up?
???????? System.Windows.Forms. application. DoEvents ();
}
?
Next get the picture from the Clipboard, WPF needs to add reference System.Windows.Forms to the project?? System.Drawing
???? if? (System.Windows.Forms. Clipboard. ContainsImage ())
???? {
??????? System.Drawing. image? image = System.Windows.Forms. Clipboard. GetImage ();
}
?
and then cut.
???? System.Drawing. Imagecutpicture (system.drawing. Image, image,int32rectwindow)
???? {
???????? Printscreen ();
???????? if? (Window. X + window. Width > Image. Width)
???????????? Window. Width = image. Width-window. X
???????? if? (Window. Y + window. Height > Image. Height)
???????????? Window. Height = image. Height-window. Y
???????? I f? (image = =null)
???????? {
???????????? //Create a new BMP image
???????????? System.Drawing. Image? bitmap =new? System.Drawing. Bitmap (Window. Width, window. Height);
???????????? //Create a new artboard
???????????? System.Drawing. Graphics? graphic = System.Drawing. Graphics. FromImage (bitmap);
???????????? //Set high quality check method
???????????? Graphic. Interpolationmode = System.Drawing.Drawing2D. Interpolationmode. High;
???????????? //Set high quality, low speed rendering smoothness
???????????? Graphic. SmoothingMode = System.Drawing.Drawing2D. SmoothingMode. highquality;
???????????? //Empty the canvas and fill it with a transparent background color
???????????? Graphic. Clear (System.Drawing. Color. Transparent);
???????????? //At the specified position and draw the specified part of the original picture at the specified size
???????????? Graphic. DrawImage (image, new?) System.Drawing. Rectangle (0, 0, window.) Width, window. Height),new? System.Drawing. Rectangle (Window. X, window. Y, window. Width, window. Height), System.Drawing. GraphicsUnit. Pixel);
???????????? returnbitmap;
????????}
???????? Else
???????? {
???????????? return? null;
????????}
}
?
Finally, wrap it up.
???? System.Drawing. Imagecutscreen (int32rectwindow)
???? {
???????? Printscreen ();
???????? Thread. Sleep (1000);
???????? if? (System.Windows.Forms. Clipboard. ContainsImage ())
???????? {
???????????? System.Drawing. Imageimage?=?cutpicture (System.Windows.Forms. Clipboard. GetImage (),int32rectwindow);
???????????? returnimage;
????????}
???????? Else
???????? {
???????????? Console. WriteLine ("clipboard doesn ' t contain picture");
???????????? returnnull;
????????}
}
System.Drawing. The Image class has an instance function save, which is simple to save and not to dwell on.
Data Source:
Http://www.cnblogs.com/zhouyinhui/archive/2010/08/20/1804762.html
https://www.mgenware.com/blog/?p=285
http://blog.csdn.net/testcs_dn/article/details/39762017
C # WPF uses the screenshot key to achieve screen capture function