Marshal - 我需要释放任何资源吗?

6

我正在使用以下方法将 byte[] 转换为 Bitmap

    public static Bitmap ByteArrayToBitmap(byte[] byteArray)
    {
        int width = 2144;
        int height = 3;
        Bitmap bitmapImage = new Bitmap(width, height, PixelFormat.Format32bppPArgb);
        BitmapData bmpData = bitmapImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppPArgb);
        IntPtr ptr = bmpData.Scan0;

        try
        {
            Marshal.Copy(byteArray, 0, ptr, byteArray.Length);
            bitmapImage.UnlockBits(bmpData);
            return bitmapImage;
        }
        finally
        {
           //Marshal.FreeHGlobal(ptr); //Do I need this?
        }
    }

我想知道这里是否需要释放任何资源? 尝试调用Marshal.FreeHGlobal(ptr),但是出现以下错误:

访问内存位置无效。

请问有人能指导一下吗?

另外,请注意,在此情况下,我可以使用MemoryStreambyte[]获取Bitmap,但是会出现“参数无效”的异常。这就是为什么我选择了Marshal的原因。

3个回答

4

如果你使用了AllocHGlobal,那么你只能使用FreeHGlobal。但是你没有使用过,所以不要调用它。你确实分配了非托管内存,这是通过new Bitmap完成的。这些内存通过Dispose()或GC在后续释放。

当然,在finally块中一定要使用UnlockBits()函数。这会“释放”指针。


2

不需要。

位图分配的内存是由位图构造函数分配的,并且在位图图像被释放时会自动释放。


1

你唯一需要做的就是确保在返回的 Bitmap 上调用 dispose 方法。最好的方法是将其放置在 using 块内。

using(Bitmap myBitmap = ByteArrayToBitmap(someArray)
{
   //...
}

你确定吗?你正在释放被返回的对象。 - Scott Chamberlain
@ScottChamberlain 你说得对,我漏看了那个。我试图删除答案,但是已被接受的答案无法删除... - MarcinJuraszek
1
我看到你在编辑时想要做什么,我进行了一些更改,希望能使它更清晰。如果我错了,请回滚。 - Scott Chamberlain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接