Я пытаюсь использовать следующий код, чтобы скопировать и растянуть часть моего растрового изображения srcBmp в мой destBmp с помощью StretchBlt - он возвращает 1, что указывает на успех, но в целевом растровом изображении ничего не нарисовано...
Код: Выделить всё
public static void StretchBltImage()
{
// create the source bitmap
var srcBmp = new Bitmap(500, 500, PixelFormat.Format32bppArgb);
var srcGfx = Graphics.FromImage(srcBmp);
srcGfx.Clear(Color.Green);
var srcHdc = srcGfx.GetHdc();
// create the target image
var destBmp = new Bitmap(200, 200, PixelFormat.Format32bppArgb);
using var destGfx = Graphics.FromImage(destBmp);
destGfx.Clear(Color.Gray);
var destHdc = destGfx.GetHdc();
var res1 = SetStretchBltMode(destHdc, STRETCH_HALFTONE);
var res2 = StretchBlt(destHdc, 75, 75, 50, 50, srcHdc, 0, 0, 100, 100, SRCCOPY);
srcGfx.ReleaseHdc(srcHdc);
destGfx.ReleaseHdc(destHdc);
destBmp.Save(".\\image.png");
}
Я пишу приложение на C#, которое успешно использует StretchBlt для захвата (и сжатия) части рабочего стола в растровое изображение с помощью следующего (упрощенного) кода.
ConsoleApp1.csproj
Код: Выделить всё
Exe
net7.0-windows
enable
enable
true
Код: Выделить всё
public static partial class Capture
{
[LibraryImport("user32")]
internal static partial nint GetDesktopWindow();
[LibraryImport("user32")]
internal static partial nint GetWindowDC(nint hWnd);
[LibraryImport("gdi32")]
internal static partial int SetStretchBltMode(
nint hdc,
int mode);
[LibraryImport("gdi32")]
internal static partial int StretchBlt(nint hdcDest, int xDest, int yDest, int , int hDest, nint hdcSrc, int xSrc, int ySrc, int wSrc, int hSrc, int rop);
private const int BLACKNESS = 0x00000042;
private const int SRCCOPY = 0x00CC0020;
private const int STRETCH_HALFTONE = 4;
public static void StretchBltScreen()
{
// open the desktop handles
var srcHwnd = GetDesktopWindow();
var srcHdc = GetWindowDC(srcHwnd);
// create the target image
var destBmp = new Bitmap(200, 200, PixelFormat.Format32bppArgb);
using var destGfx = Graphics.FromImage(destBmp);
destGfx.Clear(Color.Gray);
var destHdc = destGfx.GetHdc();
var res1 = SetStretchBltMode(destHdc, STRETCH_HALFTONE);
var res2 = StretchBlt(destHdc, 75, 75, 50, 50, srcHdc, 0, 0, 100, 100, SRCCOPY);
destGfx.ReleaseHdc(destHdc);
destBmp.Save(".\\screen.png");
}
}
Итак, если я вызываю свой StretchBltScreen в основной программе, он работает и сохраняет изображение следующим образом:

Однако сейчас я пытаюсь написать несколько модульных тестов, и мне бы хотелось выполнить StretchBlt со статическим растровым изображением в памяти, а не использовать текущий рабочий стол в качестве источника, но есть что-то не совсем правильно: StretchBlt возвращает 1, указывая на успех, но на целевом эскизе ничего не нарисовано.
Моя версия модульного теста выглядит как код вверху этого примера вопрос и в результате дает это изображение, ничего не взятое из исходного растрового изображения:

Я почти уверен, что это как-то связано с контекстами устройств, совместимыми растровыми изображениями, DIB и т. д., и пробовал различные комбинации вызовов GDI, чтобы попытаться обойти эту проблему, но на данный момент Я немного застрял в том, куда идти дальше.
Если у кого-нибудь есть какие-либо идеи, я был бы очень благодарен...