C# Image.Clone 内存不足异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/199468/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# Image.Clone Out of Memory Exception
提问by Programmin Tool
Why am I getting an out of memory exception?
为什么会出现内存不足异常?
So this dies in C# on the first time through:
所以这在 C# 中第一次通过:
splitBitmaps.Add(neededImage.Clone(rectDimensions, neededImage.PixelFormat));
splitBitmaps.Add(neededImage.Clone(rectDimensions, neededImage.PixelFormat));
Where splitBitmaps is a List<BitMap> BUT this works in VB for at least 4 iterations:
其中 splitBitmaps 是一个 List<BitMap> 但这在 VB 中至少可以工作 4 次迭代:
arlSplitBitmaps.Add(Image.Clone(rectDimensions, Image.PixelFormat))
arlSplitBitmaps.Add(Image.Clone(rectDimensions, Image.PixelFormat))
Where arlSplitBitmaps is a simple array list. (And yes I've tried arraylist in c#)
其中 arlSplitBitmaps 是一个简单的数组列表。(是的,我在 c# 中尝试过 arraylist)
This is the fullsection:
这是全文:
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 is a Bitmap by the way.
顺便说一下,需要的图像是位图。
I can't find any useful answers on the intarweb, especially not why it works just fine in VB.
我在 intarweb 上找不到任何有用的答案,尤其是为什么它在 VB 中工作得很好。
Update:
更新:
I actually found a reason (sort of) for this working but forgot to post it. It has to do with converting the image to a bitmap instead of just trying to clone the raw image if I remember.
我实际上找到了这个工作的原因(有点),但忘了发布它。如果我记得,它与将图像转换为位图有关,而不仅仅是尝试克隆原始图像。
回答by Dave Markle
Make sure that you're calling .Dispose() properly on your images, otherwise unmanaged resources won't be freed up. I wonder how many images are you actually creating here -- hundreds? Thousands?
确保您在图像上正确调用 .Dispose() ,否则不会释放非托管资源。我想知道您实际上在这里创建了多少张图片——数百张?几千?
回答by Mike L
This is a reach, but I've often found that if pulling images directly from disk that it's better to copy them to a new bitmap and dispose of the disk-bound image. I've seen great improvement in memory consumption when doing so.
这是一个范围,但我经常发现,如果直接从磁盘中提取图像,最好将它们复制到新的位图并处理磁盘绑定图像。这样做时,我看到内存消耗有很大改善。
Dave M. is on the money too... make sure to dispose when finished.
Dave M. 也在钱上……完成后一定要处理掉。
回答by Tomas Andrle
Clone() may also throw an Out of memory exception when the coordinates specified in the Rectangle are outside the bounds of the bitmap. It will not clip them automatically for you.
当 Rectangle 中指定的坐标超出位图边界时,Clone() 也可能抛出内存不足异常。它不会自动为您剪辑它们。
回答by Andy
I got this too when I tried to use the Clone() method to change the pixel format of a bitmap. If memory serves, I was trying to convert a 24 bpp bitmap to an 8 bit indexed format, naively hoping that the Bitmap class would magically handle the palette creation and so on. Obviously not :-/
当我尝试使用 Clone() 方法更改位图的像素格式时,我也遇到了这个问题。如果没记错的话,我试图将 24 bpp 位图转换为 8 位索引格式,天真地希望 Bitmap 类能够神奇地处理调色板创建等。显然不是 :-/
回答by user3283232
I found that I was using Image.Clone to crop a bitmap and the width took the crop outside the bounds of the original image. This causes an Out of Memory error. Seems a bit strange but can beworth knowing.
我发现我正在使用 Image.Clone 裁剪位图,宽度使裁剪超出了原始图像的边界。这会导致内存不足错误。看起来有点奇怪,但值得了解。
回答by dellyjm
I struggled to figure this out recently - the answers above are correct. Key to solving this issue is to ensure the rectangle is actually within the boundaries of the image. See example of how I solved this.
我最近很难弄清楚这一点 - 上面的答案是正确的。解决这个问题的关键是确保矩形实际上在图像的边界内。请参阅我如何解决此问题的示例。
In a nutshell, checked to if the area that was being cloned was outside the area of the image.
简而言之,检查被克隆的区域是否在图像区域之外。
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);