Search code examples
c++opencvbitmapbitmapdata

Convert Bitmap to Mat


I need to convert Gdiplus::Bitmap to cv::Map format. I'm using this code to do this:

Gdiplus::Bitmap* enhanced = ...; // some Bitmap
Gdiplus::BitmapData bmp_data = {};
Gdiplus::Rect rect(0, 0, enhanced->GetWidth(), enhanced->GetHeight());

enhanced->LockBits(&rect, Gdiplus::ImageLockModeRead, enhanced->GetPixelFormat(), &bmp_data);

Mat imageMap(enhanced->GetHeight(), enhanced->GetWidth(), CV_8UC3, bmp_data.Scan0, std::abs(bmp_data.Stride)); // construct Map from Bitmap data. The problem is probably here

cvNamedWindow("w", 1);
cvShowImage("w", &imageMap); // runtime error (access violation)
cvWaitKey(0);

I have an runtime error, as imageMap wasn't properly constructed. What am I doing wrong here? I will be gratefull for your explanation.


Solution

  • if you're constructing a cv::Mat from your Bitmap, you will have to use

    cv::imshow("w", imageMap);
    

    to draw it.

    again, the address of a cv::Mat is not the same as an IplImage* required by cvShowImage();

    (btw, you should get rid of all other deprecated c-api calls, too.)

    also, be a bit careful, a Mat constructed the way you do, has a borrowed pointer to the pixels.

    i don't know anything about gdi+, but if that pointer goes out of scope or gets invalid when you call enhanced->UnlockRect (or what it was called), you will need to do

    Mat safeImg = imageMap.clone();
    

    to achieve a 'deep' copy.