简体   繁体   中英

Is there a method of screenshot for all virtual display?

All the methods I've found are somehow UI dependent. So, how to capture all displays without any dependency and third party?

You can use GetSystemMetrics function with SM_CXVIRTUALSCREEN and SM_CYVIRTUALSCREEN parameters for entire desktop. It will be handle all virtual displays.

using System;
using System.ComponentModel;//You can remove it if you will catch the below exception from another layer
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;

namespace Helpers {
    public static class HelperScreenShot {

        public static void TakeAndSaveByAllScreen(ImageFormat imageFormat, string fullFileName = null) {
            var img = CopyFromScreen();
            if(img == null) return;

            if(string.IsNullOrWhiteSpace(fullFileName)) {
                fullFileName = $"{Guid.NewGuid()}.{imageFormat.ToString().ToLower()}";
            }

            img.Save(fullFileName, imageFormat);
        }

        public static byte[] TakeAsBinary(ImageFormat imageFormat) {
            using var image = CopyFromScreen();
            if(image == null) return default;

            using var ms = new MemoryStream();
            image.Save(ms, imageFormat);
            return ms.ToArray();
        }

        private static Bitmap CopyFromScreen() {
            try {
                var size = HelperDisplay.GetVirtualScreenSize();
                var image = new Bitmap(size.Width, size.Height);
                using var graphics = Graphics.FromImage(image);
                graphics.CopyFromScreen(Point.Empty, Point.Empty, size);
                return image;
            }
            catch(Win32Exception) {//When screen saver is active
                return null;
            }
        }

        private static class HelperDisplay {

            [DllImport("user32.dll")]
            private static extern int GetSystemMetrics(MetricType metricType);

            public static Size GetVirtualScreenSize() {
                var width = GetSystemMetrics(MetricType.VirtualScreenWidth);
                var height = GetSystemMetrics(MetricType.VirtualScreenHeight);
                return new Size(width, height);
            }

            private enum MetricType {
                VirtualScreenWidth = 78,
                VirtualScreenHeight = 79
            }
        }
    }
}

Usage

var dir = Path.Combine("images", "screenshot");
var imgFormat = ImageFormat.Png;
var fileName = $"{Guid.NewGuid()}.{imgFormat.ToString().ToLower()}";
fileName = Path.Combine(dir, fileName);

if(!Directory.Exists(dir)) {
    Directory.CreateDirectory(dir);
}

HelperScreenShot.TakeAndSaveByAllScreen(fileName, imgFormat);
//or 
var binaryImg = HelperScreenShot.TakeAsBinary(imgFormat);

Further Reading:

Multiple Monitor System Metrics
winuser.h header
How do you use System.Drawing in .NET Core?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM