У меня есть функция, которая делает снимок экрана определенного окна. Важно, чтобы скриншот работал независимо от того, сфокусировано ли окно / покрыто другими 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); });