WPF: Way to take screenshots

后端 未结 1 1716
谎友^
谎友^ 2020-12-01 08:27

Looking to modify the following to take a screenshot off all monitors. I have tried adapting it but my images are blank. Writing it to test.png is for testing. The byt

相关标签:
1条回答
  • 2020-12-01 09:18

    First you'll need to add references for the following namespaces:

    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Windows.Forms;
    

    Then enumerate your monitors to get the bounding rectangle for all display surfaces and pass that in to the Graphics.CopyFromScreen() method call:

    private static BitmapSource CopyScreen()
    {
        var left = Screen.AllScreens.Min(screen => screen.Bounds.X);
        var top = Screen.AllScreens.Min(screen => screen.Bounds.Y);
        var right = Screen.AllScreens.Max(screen => screen.Bounds.X + screen.Bounds.Width);
        var bottom = Screen.AllScreens.Max(screen => screen.Bounds.Y + screen.Bounds.Height);
        var width = right - left;
        var height = bottom - top;
    
        using (var screenBmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
        {
            using (var bmpGraphics = Graphics.FromImage(screenBmp))
            {
                bmpGraphics.CopyFromScreen(left, top, 0, 0, new System.Drawing.Size(width, height));
                return Imaging.CreateBitmapSourceFromHBitmap(
                    screenBmp.GetHbitmap(),
                    IntPtr.Zero,
                    Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions());
            }
        }
    }
    

    Bear in mind though that monitors often don't fit neatly into a single rectangle, particularly if they have different resolution etc, so you might be better snap-shotting the individual screens. Either way, the solution to your problem is to change the coordinates that you were passing in to the Graphics.CopyFromScreen() method call.

    EDIT: see Demetris Leptos's comment below, the code I've posted in this answer should be calling DeleteObject on the bitmap returned by screenBmp.GetHbitmap() so as to avoid a memory leak, as specified in the MSDN documentation.

    0 讨论(0)
提交回复
热议问题