0

Im using the following code to fix the Orientation of Images depending on EXIF Data

 Image FixImageOrientation(Image srce)
        {
            const int ExifOrientationId = 0x112;
            // Read orientation tag
            if (!srce.PropertyIdList.Contains(ExifOrientationId)) return srce;
            var prop = srce.GetPropertyItem(ExifOrientationId);
            var orient = BitConverter.ToInt16(prop.Value, 0);
            // Force value to 1
            prop.Value = BitConverter.GetBytes((short)1);
            srce.SetPropertyItem(prop);
          //  MessageBox.Show(orient.ToString());
            // Rotate/flip image according to <orient>
            switch (orient)
            {

                case 1:
                    srce.RotateFlip(RotateFlipType.RotateNoneFlipNone);
                    return srce;


                case 2:
                    srce.RotateFlip(RotateFlipType.RotateNoneFlipX);
                    return srce;

                case 3:
                    srce.RotateFlip(RotateFlipType.Rotate180FlipNone);
                    return srce;

                case 4:
                    srce.RotateFlip(RotateFlipType.Rotate180FlipX);
                    return srce;

                case 5:
                    srce.RotateFlip(RotateFlipType.Rotate90FlipX);
                    return srce;

                case 6:
                    srce.RotateFlip(RotateFlipType.Rotate90FlipNone);
                    return srce;

                case 7:
                    srce.RotateFlip(RotateFlipType.Rotate270FlipX);
                    return srce;

                case 8:
                    srce.RotateFlip(RotateFlipType.Rotate270FlipNone);
                    return srce;

                default:
                    srce.RotateFlip(RotateFlipType.RotateNoneFlipNone);
                    return srce;
            }
        }

I process a large batch of Images like this

for (x= 0; x<list.Count; x++)
{
filepath= list.ElementAt(x);
Bitmap image = new Bitmap(FixImageOrientation(Bitmap.FromFile(filepath)));
//Do long processing and at the end i do image.dispose();
image.dispose();
}

But when processing a large batch of images i get Out of Memory exception at

Bitmap image = new Bitmap(FixImageOrientation(Bitmap.FromFile(filepath)));

Why do i get this.. I dispose this image at the end of the loop i guess.

techno
  • 6,100
  • 16
  • 86
  • 192

3 Answers3

6

In your code you create two bitmaps but dispose only one. Change your code:

using(var source = Bitmap.FromFile(filepath)) {
    using(var image = new Bitmap(FixImageOrientation(source))) {
       // ... do long processing
    }
}

This should solve your problems.

Alessandro D'Andria
  • 8,663
  • 2
  • 36
  • 32
  • Thanks.. since image is a global Object.. i think i can simply use `using(var source = Bitmap.FromFile(filepath)) { Bitmap image = new Bitmap(FixImageOrientation(source)); } ` and dispose off `image` using `image.dispose();`.. will that work? – techno May 07 '16 at 18:00
  • @techno Sorry but I didn't understand what do you mean. You had to dispose both bitmaps. – Alessandro D'Andria May 07 '16 at 18:15
  • I meant.. im assigning `image` object in the code.I cannot do this if i use the `using` statement for `image` so i just use this `using(var source = Bitmap.FromFile(filepath)) {` and create `image` from `source` and manually dispose off `image` object...rather than using the second `using` statment. – techno May 07 '16 at 18:18
  • I cannot since .. you cannot assign value to an object that has been created using `using` statement. – techno May 07 '16 at 18:28
  • Why you need to re-assign `image`? – Alessandro D'Andria May 07 '16 at 18:32
  • If you assign another object to `image`, without previously dispose it, you will have problems with memory. If you manipulate data of `image` object (like with `SetPixel` or raw bytes) you didn't need to assign. – Alessandro D'Andria May 07 '16 at 18:37
  • I tried doing this but when i debug with large number of files i get an `outofmemory exception ` pointed here `using(var source = Bitmap.FromFile(filepath)) ` – techno May 15 '16 at 10:44
0

As you can find in this answer https://stackoverflow.com/a/7520919/6439999 the call to dispose does not necessarily free memory. This is the task of the Garbage Collector. I assume, that you are loading the images quite fast into the memory. The problem is, that the Garbage collection is only done every now and then. If you are using a huge amount of memory by creating new objects, the garbage collection might be to slow with releasing the memory again.

You could try calling it directly from within you loop with GC.Collect(). If this is not enough, you can also try the blocking parameter, which will pause your thread until the GC run has completed.

As a different approach you can set you project to compile as x64, this will give your program access to more than 1GB of memory. But with this solution you only push the problem further down the road.

Thomas

Community
  • 1
  • 1
Thomas Voß
  • 1,145
  • 8
  • 20
0

OUT OF MEMORY EXCEPTION IN FOR LOOP OF THOUSAND OF RECORD, a possible solution:

  1. use using statement in your Program for restricting scope of data base object

  2. assign null value to the list after use

  3. dispose connection object

Kos
  • 4,890
  • 9
  • 38
  • 42