2016-05-07 3 views
0

Im используя следующий код, чтобы зафиксировать ориентацию изображений в зависимости от EXIF ​​данныхИз Exception памяти при обработке большого количества изображений

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; 
      } 
     } 

Я обрабатывать большую партию изображений, как это

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(); 
} 

Но при обработке большой партии изображений я выберусь за исключением памяти в

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

Почему я это понимаю. Я располагаю это изображение в конце цикла, я думаю.

+1

Вы создаете 2 изображения и избавляетесь только один 'Bitmap.FromFile (путь_к_файл) и' нового Bitmap ('. –

+0

Ghetto путь, открытых окна задачи управления при запуске программы. Если вы видите память быстро растет, у вас где-то есть утечка памяти, –

ответ

5

В вашем коде вы создаете два растровых изображения, но располагаете только одним. Изменить код:

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

Это должно решить ваши проблемы.

+0

Спасибо .. так как изображение является глобальным объектом .. я думаю, что могу просто использовать 'using (var source = Bitmap.FromFile (путь к файлу)) {Bitmap image = new Bitmap (FixImageOrientation (source));} 'и избавиться от' image', используя 'image.dispose();' .. это будет работать? – techno

+0

@techno Извините, но я не понял, что вы имеете в виду. Вы должны были уничтожить оба растровых изображения –

+0

Я имел в виду .. im присваивание объекта 'image' в коде. Я не могу это сделать, если я использую' using' stateme nt для 'image', поэтому я просто использую это' using (var source = Bitmap.FromFile (путь к файлу)) {'и создаю' образ' из 'source' и вручную удаляем объект' image' ... вместо того, чтобы использовать второй 'использование'. – techno

0

Как вы можете найти в этом ответе https://stackoverflow.com/a/7520919/6439999 вызов для распоряжения не обязательно освобождает память. Это задача сборщика мусора. Я предполагаю, что вы быстро загружаете изображения в память. Проблема в том, что сбор мусора производят только время от времени. Если вы используете огромный объем памяти, создавая новые объекты, сборка мусора может замедляться с освобождением памяти.

Вы можете попробовать позвонить ему прямо изнутри цикла с помощью GC.Collect(). Если этого недостаточно, вы также можете попробовать параметр блокировки, который остановит ваш поток до завершения выполнения GC.

Как другой подход вы можете настроить проект на компиляцию как x64, это даст вашей программе доступ к более 1 ГБ памяти. Но с этим решением вы только продвигаете проблему дальше по дороге.

Томас

Смежные вопросы