WPF:获取屏幕截图的方法

希望修改以下内容以截取所有显示器的屏幕截图。 我试过调整它但我的图像是空白的。 将它写入test.png是为了测试。 byte[]将被发送到接收应用程序。

 public byte[] Take() { int screenWidth = Convert.ToInt32(SystemParameters.VirtualScreenWidth); int screenHeight = Convert.ToInt32(SystemParameters.VirtualScreenHeight); int screenLeft = Convert.ToInt32(SystemParameters.VirtualScreenLeft); int screenTop = Convert.ToInt32(SystemParameters.VirtualScreenTop); RenderTargetBitmap renderTarget = new RenderTargetBitmap(screenWidth, screenHeight, 96, 96, PixelFormats.Pbgra32); VisualBrush sourceBrush = new VisualBrush(); DrawingVisual drawingVisual = new DrawingVisual(); DrawingContext drawingContext = drawingVisual.RenderOpen(); using (drawingContext) { drawingContext.PushTransform(new ScaleTransform(1, 1)); drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), new Point(screenWidth, screenHeight))); } renderTarget.Render(drawingVisual); PngBitmapEncoder pngEncoder = new PngBitmapEncoder(); pngEncoder.Frames.Add(BitmapFrame.Create(renderTarget)); Byte[] _imageArray; using (MemoryStream outputStream = new MemoryStream()) { pngEncoder.Save(outputStream); _imageArray = outputStream.ToArray(); } using (FileStream stream = new FileStream(@"c:\test.png", FileMode.Create, FileAccess.ReadWrite)) { using (BinaryWriter writer = new BinaryWriter(stream)) { writer.Write(_imageArray); } } return _imageArray; } 

首先,您需要为以下命名空间添加引用:

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

然后枚举您的监视器以获取所有显示表面的边界矩形,并将其传递给Graphics.CopyFromScreen()方法调用:

 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()); } } } 

请记住,虽然显示器通常不能整齐地放入单个矩形中,特别是如果它们具有不同的分辨率等,因此您可能更好地拍摄单个屏幕。 无论哪种方式,您的问题的解决方案是将您传入的坐标更改为Graphics.CopyFromScreen()方法调用。

编辑:请参阅下面的Demetris Leptos的评论,我在这个答案中发布的代码应该是在screenBmp.GetHbitmap()返回的位图上调用DeleteObject,以避免内存泄漏,如MSDN文档中所指定的。