Re[2]: Получить screenshot windows в cv::Mat
От: Аноним  
Дата: 26.04.13 10:44
Оценка:
Выкинул один буфер.
Лучше сделать нельзя.
Закрываю тему.
Спасибо за внимание.

#include< windows.h >
#include< opencv2/opencv.hpp >

class Screen{
public:
    Screen(){
        // Параметры экрана
        HWND hwnd = GetDesktopWindow();    
        hWDC = GetWindowDC( hwnd );
        width = GetSystemMetrics( SM_CXSCREEN );
        height = GetSystemMetrics( SM_CYSCREEN );

        // Совместимый контекст в памяти
        hScreen = CreateCompatibleDC( hWDC ); // - DeleteDC( hScreen );
        hBM = CreateCompatibleBitmap( hWDC, width, height ); // - DeleteObject( hBM );
        hBM_Temp = SelectObject( hScreen, hBM ); // - SelectObject( hScreen, hBM_Temp );

        // Описание рабочего массива бит совместимого контекста в памяти
        BMI.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
        BMI.bmiHeader.biWidth = width;
        BMI.bmiHeader.biHeight = -height;
        BMI.bmiHeader.biPlanes = 1;
        BMI.bmiHeader.biBitCount = 24;
        BMI.bmiHeader.biCompression = BI_RGB;

        // Массив данных скриншота
        const int colorSize = 3; // Размер пикселя
        const int alignment = 4; // Выравнивание строки         
        int step = ( int )ceil( width * colorSize / ( double )alignment ) * alignment; // Шаг строки
        //int step = ( width * colorSize / alignment + ( width * colorSize % alignment? 1: 0 ) ) * alignment; // Шаг строки
        data = new char[ step * height ]; // - delete[] data;

        // Скриншот
        screen = new cv::Mat( height, width, CV_8UC3, data, step ); // - delete screen;
    };

    ~Screen(){
        SelectObject( hScreen, hBM_Temp );
        DeleteObject( hBM );
        DeleteDC( hScreen );
        delete screen; screen = NULL;
        delete[] data; data = NULL;
    };

    cv::Mat& get(){
        BitBlt( hScreen, 0, 0, width, height, hWDC, 0, 0, SRCCOPY );
        GetDIBits( hScreen, hBM, 0, height, data, &BMI, DIB_RGB_COLORS );
        return *screen;
    };

private:
    HDC hWDC; // Контекст экрана
    HDC hScreen; // Совместимый с экраном контекст в памяти
    HBITMAP hBM; // Рабочий массив бит совместимого контекста в памяти
    BITMAPINFO BMI; // Описание рабочего массива бит совместимого контекста в памяти

    int width; // Ширина экрана в пикселях
    int height; // Высота экрана в пикселях

    char* data; // Массив данных скриншота
    cv::Mat* screen; // Скриншот

    HGDIOBJ hBM_Temp; // Массив бит совместимого контекста в памяти созданный по умолчанию    
};

int main(){
    Screen sh;
    cv::Mat screen = sh.get();

    std::string winName = "Экран";
    cv::namedWindow( winName, 0 );
    cv::imshow( winName, screen );

    const int Space = 32;
    while( cv::waitKey( 1 ) != Space );

    cv::imwrite( "snapshot.png", screen );
    return 0;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.