C# оптимизировать скриншот определенного окна независимо от перекрытия - PullRequest
0 голосов
/ 26 марта 2020

У меня есть функция, которая делает снимок экрана определенного окна. Важно, чтобы скриншот работал независимо от того, сфокусировано ли окно / покрыто другими windows или нет, поэтому я использовал PrintWindow.

Эта функция занимает 45 мсек, чтобы завершить, и я надеялся уменьшить который. Конечная цель:

  • Сделать снимок экрана окна на основе handle, который работает, даже если окно закрыто другим окном
  • Наконец, верните byte[] для экспорта в формате PNG с использованием NodeJS.

screenshot.cs

using System.Runtime.InteropServices;
using System;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows;
using System.Windows.Forms;

public class main
{
   [StructLayout(LayoutKind.Sequential)]
   private struct Rect
   {
      public int Left;
      public int Top;
      public int Right;
      public int Bottom;
   }

   [DllImport("user32.dll")]
   private static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rect rect);

   [DllImport("user32.dll")]
   private static extern IntPtr GetClientRect(IntPtr hWnd, ref Rect rect);

   [DllImport("user32.dll")]
   private static extern IntPtr ClientToScreen(IntPtr hWnd, ref Point point);

   [DllImport("User32.dll", SetLastError = true)]
   [return: MarshalAs(UnmanagedType.Bool)]
   static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);

   public static Bitmap CaptureWindow(IntPtr handle)
   {
      var rect = new Rect();
      GetClientRect(handle, ref rect);

      var point = new Point(0,0);
      ClientToScreen(handle, ref point);

      var bounds = new Rectangle(point.X, point.Y, rect.Right, rect.Bottom);
      var result = new Bitmap(bounds.Width, bounds.Height);

      using (var graphics = Graphics.FromImage(result))
      {
         IntPtr dc = graphics.GetHdc();
         bool success = PrintWindow(handle, dc, 0);
         graphics.ReleaseHdc(dc);
      }

      return result;
   }

   public static byte[] ImageToByte(Image img)
   {
      ImageConverter converter = new ImageConverter();
      return (byte[])converter.ConvertTo(img, typeof(byte[]));
   }
}

NodeJS code

const {K, U} = require('win32-api');
const user32 = U.load();
const edge = require('edge-js');
const ss = edge.func(path.join(__dirname, 'screenshot.cs'));

var hWnd = user32.FindWindowExW(0, 0, null, Buffer.from('application\0', 'ucs2'))
ss(hWnd, function (err, r) { fs.writeFileSync("screenshot.png", r); });
...