.NET Bitmap.Clone()抛出OutOfMemoryException

时间:2016-03-19 13:01:11

标签: c# bitmap

为什么以下简单的代码片段(bitmap.Clone)会抛出OutOfMemoryException?

        List<Bitmap> bitmapList = new List<Bitmap>();
        try
        {
            for (int i = 0; i < 1000; ++i)
            {
                using (Bitmap bitmap = new Bitmap(@"C:\temp\test.gif"))
                //using (Bitmap bitmap = new Bitmap(bitmap2))
                {
                    Bitmap clonedBitmap = bitmap.Clone(new Rectangle(0, 0, bitmap.Width, bitmap.Height), PixelFormat.Format8bppIndexed);
                    bitmapList.Add(clonedBitmap);
                    Debug.WriteLine("round " + i);
                }
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }
        finally
        {
            foreach (Bitmap bitmap in bitmapList)
            {
                bitmap.Dispose();
            }
        }

首先在第95轮(有时是第94或96轮)抛出异常,因此代码在失败之前会运行很多次。原始的GIF图像不是很大,所以我无法相信这是一个真正的内存不足的情况。我知道GDI +将许多错误条件映射到OutOfMemoryException,但真正的根本原因是什么?

如果我取消注释第二个使用行并将文件位图名称更改为位图2,即我创建一个新的临时位图,然后我克隆然后代码工作正常。为什么呢?

                using (Bitmap bitmap2 = new Bitmap(@"C:\temp\test.gif"))
                using (Bitmap bitmap = new Bitmap(bitmap2))
                {

异常中的HResult是0x8007000e,根据Microsoft文档,这可能意味着内存不足等情况。也许是一些原生资源问题,但为什么它应该像这样表现出来并通过制作额外的位图来纠正?

原因不是GIF图像格式,我尝试过使用JPG和PNG图像并出现同样的问题。

我的真正目的是将24位RGB位图转换为索引的8位位图。然而,克隆产生的图像质量不是很高。任何人都知道一些更好的方法来转换为8位索引位图,还是我必须自己从头开始,包括调色板量化?

0 个答案:

没有答案