'C Win32 API display Opencv Image cv::Mat + Resizing, results in distorted, wrong colored images
So I've been looking for some simple code, on how I can display opencv images in a windows window, without using extra libraries. Most solutions that I have found use the StretchDIBits() method of the Windows API. This works fine, until I resize the window, although I call my display function after WM_SIZE and resize my image with opencv before I display it with StretchDIBits(). Sometimes the image is displayed fine, but most of the time it's distorted or even in greyscale, even though it is a RGB image.
The image resizing with opencv works fine. When I display the resized image with cv::imshow("test", imgResized); the image is displayed as expected in the same size as the resized window.
This is an image at application launch (works fine)
This is an image after resizing the window (distorted and greyscaled)
My Code
VOID ImgviewShowImg(IMGVIEW* imgView)
{
if(imgView->img == NULLPTR)
{
return;
}
cv::Mat imgResized;
POSZ inner = GetInnerPosSize(imgView);
INT width = inner.w;
INT height = inner.h;
cv::resize(*imgView->img, imgResized, cv::Size(width, height), 0, 0, cv::INTER_CUBIC);
INT bytesPerPixel = imgResized.elemSize();
BITMAPINFO bmpInfo;
memset(&bmpInfo, 0, sizeof(bmpInfo));
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = width;
bmpInfo.bmiHeader.biHeight = height;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = (bytesPerPixel * 8);
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biXPelsPerMeter = 100;
bmpInfo.bmiHeader.biYPelsPerMeter = 100;
PAINTSTRUCT paintStruct;
memset(&paintStruct, 0, sizeof(paintStruct));
HDC hdc = BeginPaint(imgView->hWnd, &paintStruct);
INT result = StretchDIBits(hdc, // HDC hdc,
0, // int xDest,
0, // int yDest,
width, // int DestWidth,
height, // int DestHeight,
0, // int xSrc,
0, // int ySrc,
width, // int SrcWidth,
height, // int SrcHeight,
imgResized.data, // const VOID *lpBits,
&bmpInfo, // const BITMAPINFO *lpbmi,
DIB_RGB_COLORS, // UINT iUsage,
SRCCOPY // DWORD rop
);
EndPaint(imgView->hWnd, &paintStruct);
}
Solution 1:[1]
Thanks to the anwser of @IInspectable and a quick google search where I found this https://gist.github.com/AhiyaHiya/6e455a3a6c846766f1017044131bfab7 with the simple solution resize(frame, frame, Size(frame.cols / 4 * 4, frame.rows));
I finally got my code to work and it now looks like this:
VOID ImgviewShowImg(IMGVIEW* imgView)
{
if(imgView->img == NULLPTR)
{
return;
}
RECT clientRect;
GetClientRect(imgView->hWnd, &clientRect);
INT wndWidth = clientRect.right - clientRect.left;
INT wndHeight = clientRect.bottom - clientRect.top;
FLOAT32 aspectRatio = (FLOAT32) wndHeight / (FLOAT32) wndWidth;
INT imgWidth = (INT) ((wndWidth / 4) * 4);
INT imgHeight = (INT) (imgWidth * aspectRatio);
cv::Mat imgResized;
cv::resize(*imgView->img, imgResized, cv::Size(imgWidth, imgHeight), 0, 0, cv::INTER_CUBIC);
INT bytesPerPixel = imgResized.elemSize();
BITMAPINFO bmpInfo;
memset(&bmpInfo, 0, sizeof(bmpInfo));
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = imgWidth;
bmpInfo.bmiHeader.biHeight = imgHeight;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = (bytesPerPixel * 8);
bmpInfo.bmiHeader.biCompression = BI_RGB;
bmpInfo.bmiHeader.biXPelsPerMeter = 100;
bmpInfo.bmiHeader.biYPelsPerMeter = 100;
PAINTSTRUCT paintStruct;
memset(&paintStruct, 0, sizeof(paintStruct));
HDC hdc = BeginPaint(imgView->hWnd, &paintStruct);
INT result = StretchDIBits(hdc, // HDC hdc,
0, // int xDest,
0, // int yDest,
wndWidth, // int DestWidth,
wndHeight, // int DestHeight,
0, // int xSrc,
0, // int ySrc,
imgWidth, // int SrcWidth,
imgHeight, // int SrcHeight,
imgResized.data, // const VOID *lpBits,
&bmpInfo, // const BITMAPINFO *lpbmi,
DIB_RGB_COLORS, // UINT iUsage,
SRCCOPY // DWORD rop
);
EndPaint(imgView->hWnd, &paintStruct);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Ambadrant |


