반응형

GDI Plus Bitmap을 OpenCV Mat으로, 다시 OpenCV Mat을 GDI Plus Bitmap으로 변환해 보자.

 

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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <windows.h>
#include <gdiplus.h>
#include <opencv2/opencv.hpp>
 
#pragma comment(lib, "gdiplus")
 
using namespace cv;
using namespace Gdiplus;
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hInst;
LPCSTR lpszClass = "Mat and Bitmap";
 
Mat originalImage;
Mat bitmapToMat;
 
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
    HWND hWnd;
    MSG Message;
    WNDCLASS WndClass;
    g_hInst = hInstance;
 
    ULONG_PTR gpToken;
    GdiplusStartupInput gpsi;
    if (GdiplusStartup(&gpToken, &gpsi, NULL!= Ok) {
        MessageBox(NULL, TEXT("GDI+ start-up error."), TEXT("GDI+ Error"), MB_OK);
 
        return 0;
    }
 
    WndClass.cbClsExtra = 0;
    WndClass.cbWndExtra = 0;
    WndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); //(HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WndClass.hInstance = hInstance;
    WndClass.lpfnWndProc = (WNDPROC)WndProc;
    WndClass.lpszClassName = lpszClass;
    WndClass.lpszMenuName = NULL;
    WndClass.style = CS_HREDRAW | CS_VREDRAW;
    RegisterClass(&WndClass);
 
    hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
        630960NULL, (HMENU)NULL, hInstance, NULL);
    ShowWindow(hWnd, nCmdShow);
 
    while (GetMessage(&Message, 000)) {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
 
    GdiplusShutdown(gpToken);
 
    return (int)Message.wParam;
}
 
Mat BitmapToMat(Bitmap* bitmap)
{
    PixelFormat pixelFormat = bitmap->GetPixelFormat();
    if (pixelFormat != PixelFormat32bppARGB) // PixelFormat24bppRGB
        return Mat();
 
    int width = bitmap->GetWidth();
    int height = bitmap->GetHeight();
    Gdiplus::Rect rectLock(00, width, height);
    Gdiplus::BitmapData bitmapData;
 
    if (bitmap->LockBits(&rectLock, Gdiplus::ImageLockModeRead, pixelFormat, &bitmapData) != Gdiplus::Ok)
        return Mat();
 
    Mat mat = Mat(height, width, CV_8UC4, // CV_8UC3
        static_cast<unsigned char*>(bitmapData.Scan0), bitmapData.Stride).clone();
 
    bitmap->UnlockBits(&bitmapData);
 
    return mat;
}
 
void OnPaint(HDC hdc)
{
    Graphics G(hdc);
 
    // Mat to Bitmap
    cvtColor(originalImage, originalImage, COLOR_BGR2BGRA);
    Bitmap bitmap((INT)originalImage.size().width, (INT)originalImage.size().height, (INT)originalImage.step,
        PixelFormat32bppARGB, originalImage.data);
    G.DrawImage(&bitmap, 00, bitmap.GetWidth(), bitmap.GetHeight());
 
    // Bitmap to Mat
    bitmapToMat = BitmapToMat(&bitmap);
 
    imshow("BitmapToMat", bitmapToMat);
}
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
 
    switch (iMessage) {
    case WM_CREATE:
        originalImage = imread("Barbara.jpg");
 
        return 0;
 
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        OnPaint(hdc);
        EndPaint(hWnd, &ps);
 
        return 0;
 
    case WM_DESTROY:
        PostQuitMessage(0);
 
        return 0;
    }
 
    return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
 

 

소스를 입력하고 빌드한다.

 

실행하면 Bitmap과 Mat 포맷의 이미지가 출력된다.

 

Mat to Bitmap 주석 부분이 Mat에서 Bitmap으로 변환의 핵심이다.

 

위 함수가 Bitmap에서 Mat으로 변환의 핵심이다.

 

반응형

'OpenCV' 카테고리의 다른 글

Compiling and Running OpenPose from Source  (2) 2022.05.15
OpenCV with C# and Camera  (0) 2021.12.29
OpenCvSharp for Network  (0) 2021.12.28
OpenCV with C#  (0) 2021.11.20
OpenCV with Qt and MSVC in Windows  (0) 2021.09.26
Posted by J-sean
: