반응형

Screen capture with Windows API and OpenCV.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <Windows.h>
#include <iostream>
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
 
using namespace std;
using namespace cv;
 
class hWnd2Mat
{
public:
    hWnd2Mat(HWND hWindow, float scale = 1);
    virtual ~hWnd2Mat();
    virtual void Read();
    Mat capture;
 
private:
    HWND hWnd;
    HDC hWindowDC, hWindowCompatibleDC;
    int height, width, srcHeight, srcWidth;
    HBITMAP hBitmap;
    BITMAPINFOHEADER bi;
};
 
hWnd2Mat::hWnd2Mat(HWND hWindow, float scale)
{
    hWnd = hWindow;
    hWindowDC = GetDC(hWnd);
    hWindowCompatibleDC = CreateCompatibleDC(hWindowDC);
    SetStretchBltMode(hWindowCompatibleDC, COLORONCOLOR);
 
    RECT windowsize;    // get the height and width of the screen
    GetClientRect(hWnd, &windowsize);
 
    srcHeight = windowsize.bottom;
    srcWidth = windowsize.right;
    height = (int)(windowsize.bottom * scale);
    width = (int)(windowsize.right * scale);
 
    capture.create(height, width, CV_8UC4);
 
    // create a bitmap
    hBitmap = CreateCompatibleBitmap(hWindowDC, width, height);
    bi.biSize = sizeof(BITMAPINFOHEADER);    // http://msdn.microsoft.com/en-us/library/windows/window/dd183402%28v=vs.85%29.aspx
    bi.biWidth = width;
    bi.biHeight = -height;  //this is the line that makes it draw upside down or not
    bi.biPlanes = 1;
    bi.biBitCount = 32;
    bi.biCompression = BI_RGB;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0;
 
    // use the previously created device context with the bitmap
    SelectObject(hWindowCompatibleDC, hBitmap);
};
 
void hWnd2Mat::Read()
{
    // copy from the window device context to the bitmap device context
    StretchBlt(hWindowCompatibleDC, 00, width, height, hWindowDC, 00, srcWidth, srcHeight, SRCCOPY);
    //change SRCCOPY to NOTSRCCOPY for wacky colors!
    GetDIBits(hWindowCompatibleDC, hBitmap, 0, height, capture.data, (BITMAPINFO*)&bi, DIB_RGB_COLORS);
    //copy from hWindowCompatibleDC to hBitmap
};
 
hWnd2Mat::~hWnd2Mat()
{
    DeleteObject(hBitmap);
    DeleteDC(hWindowCompatibleDC);
    ReleaseDC(hWnd, hWindowDC);
};
 
int main()
{
    HWND hWndDesktop = GetDesktopWindow();
    hWnd2Mat desktop(hWndDesktop, 1);    // scale = 1
 
    cout << "Screen capure in 3 seconds." << endl;
    
    for (int i = 3; i > 0; i--)
    {
        cout << i << ".." << endl;
        Sleep(1000);
    }
 
    desktop.Read();
    imshow("Capture", desktop.capture);
 
    waitKey();
 
    return 0;
}



It captures your desktop image in 3 seconds.


반응형
Posted by J-sean
: