Как сделать скриншот с использованием C++?

Как можно сделать скрины на C++ и прочитать цвета пикселей без использования GDI+? GDI+ приводит к большому потреблению памяти, и мне не требуется сохранение изображения, только чтение цветов пикселей.
  • 8 февраля 2024 г. 8:09
Ответы на вопрос 2
Для создания скриншота и считывания пикселей в C++ на Windows вы можете использовать WinAPI, в частности функции из GDI, а не GDI+. Пример кода, демонстрирующего, как сделать скриншот экрана и считать цвета пикселей, может выглядеть примерно так:

```cpp
#include <windows.h>

int main() {
    // Получаем дескриптор для рабочего стола
    HDC hScreenDC = GetDC(NULL);
    // Создаем совместимый контекст устройства
    HDC hMemoryDC = CreateCompatibleDC(hScreenDC);

    int width = GetSystemMetrics(SM_CXSCREEN);
    int height = GetSystemMetrics(SM_CYSCREEN);

    // Создаем битмап, куда будет скопировано содержимое экрана
    HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height);

    // Выбираем битмап в памяти
    HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemoryDC, hBitmap);

    // Копируем содержимое экрана в битмап
    BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);
    hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap);

    // Теперь вы можете считывать цвет каждого пикселя как:
    COLORREF color;
    int x = 10; // координата X пикселя, который нужно прочитать
    int y = 20; // координата Y пикселя, который нужно прочитать
    color = GetPixel(hMemoryDC, x, y);

    // Не забываем освободить ресурсы
    DeleteDC(hMemoryDC);
    ReleaseDC(NULL, hScreenDC);
    DeleteObject(hBitmap);

    return 0;
}
```

Этот код создает скриншот всего экрана и позволяет считать цвета отдельных пикселей. Он использует непосредственно GDI через функции WinAPI, такие как `GetDC()`, `CreateCompatibleDC()`, `CreateCompatibleBitmap()`, `BitBlt()`, `SelectObject()`, и `GetPixel()`.

Не забывайте, что для работы с такими операциями, как создание скриншотов в C++, вам понадобятся адекватные права пользователя, и ваше приложение должно работать в среде, где есть доступ к GDI.

Если вам нужно работать с большим количеством пикселей, множественные вызовы `GetPixel` могут быть неэффективными по скорости исполнения. В таком случае лучше использовать буфер битмапа, чтобы вытягивать все пиксели одновременно и затем работать с ними непосредственно в памяти. Это можно сделать с помощью `GetDIBits`, которая извлекает битовые данные изображения и позволяет вам легко получить доступ ко всему массиву пикселей.

Обратите внимание, что работа с низкоуровневыми ресурсами в Windows требует основательного понимания API и управления ресурсами. Неправильное использование может привести к утечкам памяти или другим ошибкам.
На винде? Кроме gdi+ можно ещё через directx (гуглите  dxgi duplicator) или через windows graphics capture api. Но последние 2 не работают в старых системах. 

Если же вам только посмотреть на несколько пикселей, то можно и в gdi+ делать скриншот лишь маленькой части, или вообще ничего не копировать и смотреть на цвет пикселей в экранном DC.
Похожие вопросы