C# Image.Clone Out of Memory Exception

2020-01-25 07:57发布

Why am I getting an out of memory exception?

So this dies in C# on the first time through:

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

Where splitBitmaps is a List<BitMap> BUT this works in VB for at least 4 iterations:

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

Where arlSplitBitmaps is a simple array list. (And yes I've tried arraylist in c#)

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.

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.

6条回答
一夜七次
2楼-- · 2020-01-25 08:14

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.

查看更多
可以哭但决不认输i
3楼-- · 2020-01-25 08:18

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.

查看更多
相关推荐>>
4楼-- · 2020-01-25 08:18

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?

查看更多
对你真心纯属浪费
5楼-- · 2020-01-25 08:24

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);
查看更多
不美不萌又怎样
6楼-- · 2020-01-25 08:32

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.

查看更多
做个烂人
7楼-- · 2020-01-25 08:32

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 :-/

查看更多
登录 后发表回答