Reputation:
I want to load an image using OpenCV and then display it on a window.
I know how to load an image using opencv and how to create a window using win32 but how do I go about putting the image / mat from Opencv on the window afterwards?
This is how I load the image from opencv:
#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <string>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
string imageName("C:/image.jpg"); // by default
if (argc > 1)
{
imageName = argv[1];
}
Mat image;
image = imread(imageName.c_str(), IMREAD_COLOR);
if (image.empty())
{
cout << "Could not open or find the image" << std::endl;
return -1;
}
namedWindow("Display window", WINDOW_AUTOSIZE);
imshow("Display window", image);
waitKey(0);
return 0;
}
EDIT: The reason I want to do this is actually not to create a window during runtime and then display the image on it, but rather I want to find a window using win32's FindWindow function and then draw an image on that :D
Upvotes: 0
Views: 5694
Reputation: 401
I'm using this pretty often with my MFC projects. If you only have hwnd, not CWnd, then you may have to change a bit.
This works both with 8-bit RGB color and 1-channel monochrome image.
void DrawImage( CWnd *wnd, int width, int height, int bpp, const unsigned char *buffer)
{
RECT rect;
wnd->GetWindowRect(&rect);
CDC *dc = wnd->GetDC();
if( bpp == 3) // BGR
{
BITMAPINFO bmpinfo;
memset(&bmpinfo, 0, sizeof(bmpinfo));
bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpinfo.bmiHeader.biBitCount = 24;
bmpinfo.bmiHeader.biClrImportant = 0;
bmpinfo.bmiHeader.biClrUsed = 0;
bmpinfo.bmiHeader.biCompression = BI_RGB;
bmpinfo.bmiHeader.biWidth = width;
bmpinfo.bmiHeader.biHeight = -height;
bmpinfo.bmiHeader.biPlanes = 1;
bmpinfo.bmiHeader.biSizeImage = 0;
bmpinfo.bmiHeader.biXPelsPerMeter = 100;
bmpinfo.bmiHeader.biYPelsPerMeter = 100;
::SetStretchBltMode( dc->GetSafeHdc(), COLORONCOLOR);
::StretchDIBits( dc->GetSafeHdc(),
0,
0,
rect.right - rect.left,
rect.bottom - rect.top,
0,
0,
width,
height,
buffer,
&bmpinfo,
DIB_RGB_COLORS,
SRCCOPY);
}
else if ( bpp == 1) // monochrome.
{
char bitmapInfoBuf[sizeof(BITMAPINFO) + 4 * 256];
BITMAPINFO* pBmpInfo = (BITMAPINFO*)bitmapInfoBuf;
memset(pBmpInfo, 0, sizeof(BITMAPINFO) + 4 * 256);
pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pBmpInfo->bmiHeader.biWidth = width;
pBmpInfo->bmiHeader.biHeight = -height;
pBmpInfo->bmiHeader.biCompression = BI_RGB;
pBmpInfo->bmiHeader.biPlanes = 1;
pBmpInfo->bmiHeader.biBitCount = 8;
for(int i = 0; i < 256; i++)
{
pBmpInfo->bmiColors[i].rgbBlue=i;
pBmpInfo->bmiColors[i].rgbGreen=i;
pBmpInfo->bmiColors[i].rgbRed=i;
pBmpInfo->bmiColors[i].rgbReserved=255;
}
::SetStretchBltMode( dc->GetSafeHdc(), COLORONCOLOR);
::StretchDIBits( dc->GetSafeHdc(),
0,
0,
rect.right - rect.left,
rect.bottom - rect.top,
0,
0,
width,
height,
buffer,
pBmpInfo,
DIB_RGB_COLORS,
SRCCOPY);
}
wnd->ReleaseDC(dc);
}
void DrawCVImage(cv::Mat image, CWnd *picture)
{
if (image.cols % 4 == 0)
{
DrawImage(picture,
image.cols,
image.rows,
image.channels() == 3 ? 3 : 1,
image.data);
}
else
{
Mat image2(image.rows, image.cols + ( 4 - image.cols % 4), image.type());
image2 = 0;
image.copyTo(image2(Rect(0, 0, image.cols, image.rows)));
DrawImage(picture,
image2.cols,
image2.rows,
image2.channels() == 3 ? 3 : 1,
image2.data);
}
}
Upvotes: 1
Reputation: 650
Well...
Don't create a new window by calling "namedWindow()".
Then call imshow(nameOfExistingWindow, image)
.
Maybe it will work.
Upvotes: 0