Как сделать скриншот всего экрана из консольного приложения .NET 6 с помощью GDI+?
Мне нужно делать скриншот экрана в некоторый момент выполнения программы, я находил несколько ответов как это делать, но они не работают. Я включал System.Windows.Forms и System.Drawing в проект, скачивал через nuget System.Drawing.Common который решает ошибки при компиляции, но при попытке сделать скриншот выдает ошибку о GDI+, пытался добавить ссылки на эти же библиотеки в COM, но всё тщетно.
Текущий код:
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.CopyFromScreen(Point.Empty, Point.Empty, bitmap.Size);
bitmap.Save("C:\\img.png");
Ответы (1 шт):
Windows Forms не нужно, это лишнее.
1. Создаю пустое .NET 6 приложение.
2. Устанавливаю NuGet пакет System.Drawing.Common
3. Правлю TargetFramework проекта на net6.0-windows, чтобы IDE не ругалась о несовместимости приложения с другими платформами.
В результате .csproj файл выглядит вот так
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
</ItemGroup>
</Project>
4. Разрешение моего монитора 3840x2400, то есть потребуется поддержка мониторов с высоким DPI. Чтобы она появилась, просто вызову метод WinAPI SetProcessDPIAware, и тогда система будет знать, что мое приложение умеет работать с физическими мониторами с DPI, отличным от 96.
Получается такой код:
using System.Diagnostics;
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
namespace ScreenshotGdi;
class Program
{
[DllImport("user32.dll")]
static extern bool SetProcessDPIAware();
static Size GetMonitorSize()
{
IntPtr hwnd = Process.GetCurrentProcess().MainWindowHandle;
using Graphics g = Graphics.FromHwnd(hwnd);
return new Size((int)g.VisibleClipBounds.Width, (int)g.VisibleClipBounds.Height);
}
static Bitmap TakeScreenshot(Size size)
{
Bitmap bmp = new Bitmap(size.Width, size.Height);
using Graphics graphics = Graphics.FromImage(bmp);
graphics.CopyFromScreen(Point.Empty, Point.Empty, bmp.Size);
return bmp;
}
static void Main(string[] args)
{
SetProcessDPIAware();
Size monitorSize = GetMonitorSize();
using Bitmap bitmap = TakeScreenshot(monitorSize);
bitmap.Save("img.png", ImageFormat.Png);
}
}
И вот такой скриншот
Делать скриншоты можно еще с помощью DirectX
