Проблема при попытке использовать GetDIBits для захвата части экрана/окна.C#

Место общения программистов C#
Ответить
Anonymous
 Проблема при попытке использовать GetDIBits для захвата части экрана/окна.

Сообщение Anonymous »

Контекст: я пытаюсь написать небольшой код, который сможет определять частоту кадров целевого окна. Моя текущая цель — использовать контрольную сумму, чтобы проверить, изменилось ли окно. В конкретной ситуации я хочу использовать это для перемещения содержимого окна в режиме прокрутки, поэтому небольшой счетчик шагов для контрольной суммы подойдет.
Справочная информация: когда я впервые начал писать В этом коде я быстро заметил, что функция GetPixel (gdi32) работает очень медленно, поэтому проверка всего 100 пикселей занимает более 2000 мс.
После пары поисков в Google я наткнулся на метод использования собственного растрового изображения для чтения части контекста устройства, который, очевидно, был намного быстрее, чем GetPixel, даже для чтения отдельных пикселей.
Проблема: насколько я могу судить, метод GetDIBits ( gdi32) ничего не записывает в мой выходной массив. Используя точки останова, я заметил, что буфер и выходной массив остались равными 0, а использование базового цикла for для рандомизации содержимого массивов подтвердило, что значения не записываются как 0, они просто не записываются.
Основная часть рассматриваемого кода такова:

Код: Выделить всё

public RGBQuad[] GetBitmap(int x, int y, uint width, uint height)
{
var newDC = CreateCompatibleDC(context);
var map = CreateCompatibleBitmap(context, width, height);
SelectObject(newDC,map);
var info = new BitmapInfo();
info.header.bitCount = 32;
info.header.compression = 0; // BI_RGB
info.header.planes = 1;
info.header.width = width;
info.header.height = height;
info.header.size = biSize;
var pixels = new RGBQuad[width * height];
BitBlt(newDC, 0, 0, width, height, context, x, y, 13369376 /*SRCCOPY*/);
GetDIBits(newDC, map, 0, height, pixels, ref info, 0 /*DIB_RGB_COLORS*/);
DeleteObject(map);
DeleteDC(newDC);
return pixels;
}
Примечание. Я пробовал использовать этот код как с контекстом оконного устройства, так и с контекстом экранного устройства.
это мои объявления для внешних методов.

Код: Выделить всё

[DllImport("gdi32")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr context, uint width, uint height);
[DllImport("gdi32")]
public static extern IntPtr CreateCompatibleDC(IntPtr context);
[DllImport("gdi32")]
public static extern bool DeleteDC(IntPtr context);
[DllImport("gdi32")]
public static extern IntPtr SelectObject(IntPtr context, IntPtr obj);
[DllImport("gdi32")]
public static extern bool DeleteObject(IntPtr obj);
[DllImport("gdi32")]
public static extern bool BitBlt(IntPtr dstContext, int dstX, int dstY, uint width, uint height, IntPtr srcContext, int srcX, int srcY, uint operation);
[DllImport("gdi32")]
public static extern int GetDIBits(IntPtr context, IntPtr bitmap, uint start, uint lines, RGBQuad[] bits, ref BitmapInfo header, uint usage);
Не стесняйтесь спрашивать любые разъяснения


Подробнее здесь: https://stackoverflow.com/questions/791 ... een-window
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»