Bitmap
클래스에는 getHbitmap()
이란 함수가 있다.
반환형은 IntPtr
이며, Bitmap
자체의 포인터를 돌려준다.(복사X)
이를 C++ 측에서 인수로 받아 HBITMAP 으로 형변환을 해준뒤 아래의 함수를 호출하면 된다.
HWND GetHwnd() {
DWORD pid = GetCurrentProcessId();
if (pid == 0 || pid == -1)return NULL;
LPARAM tmp = 0;
tmp = (LPARAM)pid;
EnumWindows([](HWND hwnd, LPARAM lparam)->BOOL {
HANDLE hTarget = NULL;
DWORD dwID = 0;
DWORD dwSrcID = (DWORD)(*(DWORD*)lparam);
GetWindowThreadProcessId(hwnd, &dwID);
if (dwID == dwSrcID) {
*((int*)lparam) = *(DWORD*)hwnd;
*(((int*)lparam) + 1) = 1;
return FALSE;
}
return TRUE;
}, (LPARAM)&tmp);
if (((int)(tmp >> 32))) {
return (HWND)tmp;
}
return GetConsoleWindow();
}
cv::Mat HBITMAP2cvMat(HBITMAP hbmp, HWND hwnd) {
cv::Mat img;
HDC hdc = GetDC(hwnd);
BITMAPINFO bmi;
BITMAPINFOHEADER* bmih = &(bmi.bmiHeader);
ZeroMemory(bmih, sizeof(BITMAPINFOHEADER));
bmih->biSize = sizeof(BITMAPINFOHEADER);
if (GetDIBits(hdc, hbmp, 0, 0, NULL, &bmi, DIB_RGB_COLORS)) {
int height = (bmih->biHeight > 0) ? bmih->biHeight : -bmih->biHeight;
int channels = (bmih->biSizeImage / (bmih->biWidth*bmih->biHeight));
img = cv::Mat(height, bmih->biWidth, CV_MAKE_TYPE(CV_8U,channels));
bmih->biBitCount = 8* channels;
bmih->biCompression = BI_RGB;
GetDIBits(hdc, hbmp, 0, height, img.data, &bmi, DIB_RGB_COLORS);
}
ReleaseDC(NULL, hdc);
cv::flip(img, img, 0);
switch (img.channels()) {
case 4:cv::cvtColor(img, img, CV_BGRA2BGR); break;
case 1:cv::cvtColor(img, img, CV_GRAY2BGR); break;
default:break;
}
return img;
}
HBITMAP을 IplImage로 바꾸는 코드는 아래와 같다.
IplImage* HBMPtoIPL(HBITMAP hbmp) {
static HWND hwnd = nullptr;
if (hwnd == nullptr) {
char pszNewWindowTitle[1024];
char pszOldWindowTitle[1024];
GetConsoleTitleA(pszOldWindowTitle, 1024);
sprintf(pszNewWindowTitle, "%d/%d", GetTickCount(), GetCurrentProcessId());
SetConsoleTitleA(pszNewWindowTitle);
while (hwnd == nullptr) {
hwnd = FindWindowA(NULL, pszNewWindowTitle);
Sleep(1);
}
SetConsoleTitleA(pszOldWindowTitle);
}
HDC hdc = GetDC(hwnd);
IplImage* Image = NULL;
BITMAPINFO bmi;
BITMAPINFOHEADER* bmih = &(bmi.bmiHeader);
ZeroMemory(bmih, sizeof(BITMAPINFOHEADER));
bmih->biSize = sizeof(BITMAPINFOHEADER);
if (GetDIBits(hdc, hbmp, 0, 0, NULL, &bmi, DIB_RGB_COLORS)) {
int height = (bmih->biHeight > 0) ? bmih->biHeight : -bmih->biHeight;
Image = cvCreateImage(cvSize(bmih->biWidth, height), IPL_DEPTH_8U, 3);
Image->origin = (bmih->biHeight > 0);
bmih->biBitCount = 24;
bmih->biCompression = BI_RGB;
GetDIBits(hdc, hbmp, 0, height, Image->imageData, &bmi, DIB_RGB_COLORS);
}
ReleaseDC(NULL, hdc);
return Image;
}