C# Image.Clone Out of Memory Exception

43,393

Solution 1

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.

Solution 2

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.

Solution 3

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

Solution 4

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.

Solution 5

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);
Share:
43,393
Programmin Tool
Author by

Programmin Tool

It should be illegal to be this awesome. Then again if it were, I would have been put to death a long time ago.

Updated on July 09, 2022

Comments

  • Programmin Tool
    Programmin Tool almost 2 years

    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.

  • Programmin Tool
    Programmin Tool over 15 years
    Doubt it's memory, blows up first time through.
  • Jared Updike
    Jared Updike over 14 years
    Yeah bitmap .Dispose doesn't affect these OoM exceptions, in my experience.
  • CrnaStena
    CrnaStena almost 10 years
    For me this was an issue between using Windows 2003 Server and Windows 7 or Windows 2008 Server. Cloning with some PixelFormats fails on Windows 2003.
  • hawkke
    hawkke almost 10 years
    Just a quick note in case it isn't obvious (it wasn't to me at first): the width and height parameters of the rectangle constructor represent the area of the rectangle you want, not the bottom-right coords. Ex. on a 100x100 image, if you want the rectangle (15,10) to (100,100), you need new Rectangle(15, 10, 85, 90). Width = image width-x (100-15=85), height = image height-y (100-10=90). Rectangle(15,10,100,100) will give you an out of memory exception.
  • dellyjm
    dellyjm over 9 years
    Dead horse but thought it was good to highlight what TomA and Brian mentioned... MSDN has it [link]msdn.microsoft.com/en-us/library/ms141944(v=vs.110).as‌​px[link] OutOfMemoryException rect is outside of the source bitmap bounds.
  • Rami A.
    Rami A. over 6 years
    Thank you. For reference, you can just use the Intersect method instead of doing the calculations yourself: rect.Intersect(new Rectangle(0, 0, localImage.Width, localImage.Height)); :)
  • dashesy
    dashesy almost 5 years
    Could this happen when converting to Format24bppRgb? I am tracking an issue, but cannot seem to find an image that could cause this exception
  • A X
    A X almost 5 years
    I hereby submit this Microsoft error message as one of the top 10 worst SDK error messages of all time.
  • A X
    A X almost 5 years
    By the way this was very helpful and correct, thank you