内存exception的C#Image.Clone

为什么我得到一个内存不足的例外?

所以这在C#中首次通过:

splitBitmaps.Add(neededImage.Clone(rectDimensions,neededImage.PixelFormat));

其中splitBitmaps是一个列表<BitMap>但这在VB中至less4次迭代:

arlSplitBitmaps.Add(Image.Clone(rectDimensions,Image.PixelFormat))

其中arlSplitBitmaps是一个简单的数组列表。 (是的,我试过在C#中的arraylist)

这是完整的部分:

for (Int32 splitIndex = 0; splitIndex <= numberOfResultingImages - 1; splitIndex++) { Rectangle rectDimensions; if (splitIndex < numberOfResultingImages - 1) { rectDimensions = new Rectangle(splitImageWidth * splitIndex, 0, splitImageWidth, splitImageHeight); } else { rectDimensions = new Rectangle(splitImageWidth * splitIndex, 0, sourceImageWidth - (splitImageWidth * splitIndex), splitImageHeight); } splitBitmaps.Add(neededImage.Clone(rectDimensions, neededImage.PixelFormat)); 

}

neededImage是一个位图的方式。

在intarweb上我找不到任何有用的答案,特别是为什么它在VB中工作得很好。

更新:

我实际上find了一个这样的工作的原因,但忘了发布。 它与图像转换为位图,而不是如果我记得只是试图克隆原始图像。

当Rectangle中指定的坐标超出位图范围时,Clone()也可能会抛出内存不足exception。 它不会自动为你剪切它们。

我发现我正在使用Image.Clone来裁剪一个位图,宽度使作物超出了原始图像的范围。 这会导致内存不足错误。 似乎有点奇怪,但可以beworth知道。

当我尝试使用Clone()方法更改位图的像素格式时,我也得到了这一点。 如果内存服务,我试图将24 bpp位图转换为8位索引格式,天真地希望Bitmap类会奇迹般地处理调色板创build等等。 很明显不是 :-/

这是一个范围,但我经常发现,如果直接从磁盘中提取图像,最好将它们复制到一个新的位图并处理磁盘绑定的图像。 在这样做的时候,我看到内存消耗有了很大的提高。

Dave M.也是这样的钱…确保完成后处置。

确保你正在调用.Dispose()正确的图像,否则非托pipe资源将不会被释放。 我想知道你在这里创造了多less图片 – 数百? 成千上万的?

我最近努力弄清楚这一点 – 上面的答案是正确的。 解决这个问题的关键是确保矩形实际上在图像的边界内。 看到我如何解决这个问题的例子。

简而言之,检查被克隆的区域是否在图像的区域之外。

 int totalWidth = rect.Left + rect.Width; //think -the same as Right property int allowableWidth = localImage.Width - rect.Left; int finalWidth = 0; if (totalWidth > allowableWidth){ finalWidth = allowableWidth; } else { finalWidth = totalWidth; } rect.Width = finalWidth; int totalHeight = rect.Top + rect.Height; //think same as Bottom property int allowableHeight = localImage.Height - rect.Top; int finalHeight = 0; if (totalHeight > allowableHeight){ finalHeight = allowableHeight; } else { finalHeight = totalHeight; } rect.Height = finalHeight; cropped = ((Bitmap)localImage).Clone(rect, System.Drawing.Imaging.PixelFormat.DontCare);