1

I have to import a large amount of image crops off of many images that are all ready stored in my database. I have tried using statements and disposing of my bitmap objects each time. But I am still getting a Memory Overflow Exception that my system is out of memory.

Here is some sample code of what I am doing.

public void CropImage(List<ImageClass> data)
{
    foreach (var obj in data)
    {
        //I have a data base method that returns a data object that 
        //contains the file bytes of the image id in data: 'file'
        //My List<ImageClass> data contains an ID of the original image
        //start x,y coords for the upper left corner of the rectangle,
        //and the width and height of the rectangle.

        Image img = Image.FromStream(new MemoryStream(file.Data));
        Bitmap bmp = new Bitmap((Bitmap)img);
        Rectangle cropArea = new Rectangle(obj.x_coordinate,
                                           obj.y_coordinate,
                                           obj.width,
                                           obj.height);

        Bitmap cropImage = bmp.Clone(cropArea, bmp.PixelFormat);

        SaveFile(cropImage, file, obj.scanID);

        img.Dispose();
        bmp.Dispose();
        cropImage.Dispose();
    }
}


    public void SaveFile(Bitmap cropImage, FileData file, int OCRscanID)
    {
        EncoderParameters encoderParams = new EncoderParameters();
        encoderParams.Param[0] = new EncoderParameter(
                                          System.Drawing.Imaging.Encoder.Quality,
                                          50L);

        ImageCodecInfo codecInfo = GetEncoderInfo("image/jpeg");
        MemoryStream newImage = new MemoryStream();
        cropImage.Save(newImage, codecInfo, encoderParams);

        byte[] newData = newImage.ToArray();

        //Saving data bytes to database of the cropped image 
    }

    private ImageCodecInfo GetEncoderInfo(string mimeType)
    {
        int j;
        ImageCodecInfo[] encoders;
        encoders = ImageCodecInfo.GetImageEncoders();
        for (j = 0; j < encoders.Length; ++j)
        {
            if (encoders[j].MimeType == mimeType)
                return encoders[j];
        }
        return null;
    }

I know I can trim up some of the code like searching for an encoder to just use the image/jpeg. But i had another application for this code another project. I just can't seem to get past the memory overflow.

I need to cycle through about 20k images.

tshepang
  • 12,111
  • 21
  • 91
  • 136
Tom
  • 1,047
  • 3
  • 24
  • 44

3 Answers3

5

You're not disposing your memory streams. Everything that implements IDisposable should be disposed.

Is a memory leak created if a MemoryStream in .NET is not closed?

Community
  • 1
  • 1
Samuel Neff
  • 73,278
  • 17
  • 138
  • 182
  • this is true, but won't cause a leak as implemented. Obviously you should still call dispose and not rely on the implementation details of MemoryStream. – Yaur Jul 08 '11 at 01:13
  • @Yaur, you're probably right. But, when something isn't working, start by eliminating everything that is wrong, no matter how trivial, until you find the real cause. – Samuel Neff Jul 09 '11 at 03:53
  • This was really it. I was having 2 memory streams opened. Big mistake when dealing with this much data. Also I was just bringing in a new memory stream and never defining it...or disposing of it. I created a VERY stripped down version that works and no memory leak. Processes cropping of each image in about .27 seconds. – Tom Jul 11 '11 at 15:41
1

Ants memory profiler is an invaluable tool for debugging these types of problems. At first glance the only problem I see is that you have a leak if you ever throw an exception.

what I would do is to use using instead of manually disposing your objects and make sure you are logging exceptions. If that doesn't do it and the memory profiler doesn't show you any problems try adding a GC.collect() as this may help if your large object heap is getting fragmented, which is relatively likely with this sort of code.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Yaur
  • 7,333
  • 1
  • 25
  • 36
0

There are a certain number of options available to you which can be helpful like bitmap compress , bitmap recycle , bitmap scaling , catching bitmaps.

Catching Bitmaps

Catching OutOfMemoryError in decoding Bitmap

Recycle bitmaps

Android: Bitmap recycle() how does it work?

Bitmap compress

How to make Bitmap compress without change the bitmap size?

Bitmap scaling

Android - Scale and compress a bitmap

Community
  • 1
  • 1