0
votes

In my situation, the Drawing::Bitmap is created using a pointer to the pixel data. On the MSDN you can find a constructor doing exactly this:

Bitmap(int width, int height, int stride, PixelFormat format, IntPtr scan0);

From the documentation it is clear this constructor creates just the header and required things around the provided data. It is also noted, the caller have to release the pixel data array.

The caller is responsible for allocating and freeing the block of memory specified by the scan0 parameter. However, the memory should not be released until the related Bitmap is released.

My problem is, if I pass a Bitmap with linked pixel data to another class, then I'm not able to release the underlying data. See my example bellow:

Drawing::Image^ FirstClass::GetImage(std::string ImagePath)
{
    IplImage* cvImg = cvLoadImage(ImagePath.c_str());
    Drawing::Image^ ManagedImg = gcnew Bitmap(
            cvImg->width, 
            cvImg->height, 
            cvImg->widthStep, 
            Drawing::Imaging::PixelFormat::Format24bppRgb, 
            (System::IntPtr)cvImg->imageData);
    return ManagedImg;
}


Void SecondClass::RefreshImage()
{
    // Release the last image first
    if (MyImage!=nullptr)
    {
        ???
    }

    MyImage = GetImage(...);
}

A simple workaround is to pass, the IplImage* to the SecondClass, create the managed Bitmap there and then call cvReleaseImage(&Native_MyImage); there. However this works, I really want to know how to do it properly without passing IplImage*.

1

1 Answers

1
votes

You need to pass pointers to pixels in some way.

For me, a better way would be to wrap IplImage* and ManagedImg into a single class that manages both of them. The destructor of the class would be responsible for destroying ManagedImg and then for calling cvReleaseImage() for stored value of the IplImage*. And then your GetImage function could return a pointer to this wrapper class, not to Drawing::Image.