为什么以下简单的代码片段(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位索引位图,还是我必须自己从头开始,包括调色板量化?