Ankit
Ankit

Reputation: 663

C#: Bitmap Creation using bytes array

I am trying to dynamically create a Bitmap Image using byte array using following code

Bitmap GetImage()
{
    IntPtr  ip = Marshal.AllocCoTaskMem(imagesize);

    //some code to fill ip

    Image img =  new Bitmap(
                    w,
                    h,
                    -stride,
                    PixelFormat.Format24bppRgb,
                    (IntPtr)(ip.ToInt32() + imagesize - stride)
                    );

    Marshal.FreeCoTaskMem( ip); // Comment this line to work

    return img;
}

void SaveImage()
{
    Image img =  GetImage();
    img.save("test.bmp"); // This call fails
    img.Dispose();
}

Now my problem is I want to return a Bitmap but at the same time I don't want to keep the ip pointer as that memory allocated leaks. It is never freed. How can I return a Image created with bytes array and without bothering the caller of the function GetImage() to free up the memory.

Upvotes: 2

Views: 4761

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1503439

The simplest way may be to create the bitmap (although in similar code I've used a normal byte[] and then a fixed block, rather than directly using AllocCoTaskMem), and then create a second Bitmap of the same size. Call Graphics.FromImage on the second bitmap, then Graphics.DrawImage using the first bitmap to effectively copy the contents of the first bitmap onto the second. You can then call Dispose on the first bitmap, release the memory, and use the second bitmap which is basically a copy.

There may well be a more efficient way to do it if you're more proficient with image stuff, but if you're just looking for a way to get it to work, it's a starting point :)

EDIT: zachrrs's comment does indeed make things easier using the Bitmap(Image) constructor:

using (Bitmap original = new Bitmap(...))
{
    Bitmap copy = new Bitmap(originalImage);
    // Then return "copy" from your method, and you can free the
    // memory
}

Upvotes: 4

Lucero
Lucero

Reputation: 60276

If you know the dimensions in advance, why not creating the bitmap and use the Bitmap.LockBits method to get the input buffer address?

Upvotes: 0

Related Questions