Подтвердить что ты не робот

С# Image.Clone Out of Memory Exception

Почему я получаю исключение из памяти?

Таким образом, это первый раз умирает в С# через:

splitBitmaps.Add(необходимоImage.Clone(rectDimensions, neededImage.PixelFormat));

Если splitBitmaps - это List <BitMap> НО это работает в VB как минимум за 4 итерации:

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

Где arlSplitBitmaps - это простой список массивов. (И да, я попробовал arraylist в С#)

Это полная секция:

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 - это растровое изображение.

Я не могу найти полезных ответов на intarweb, особенно не потому, что он отлично работает в VB.

Update:

Я действительно нашел причину (вроде) для этой работы, но забыл ее опубликовать. Это связано с преобразованием изображения в растровое изображение вместо того, чтобы просто клонировать исходное изображение, если я помню.

4b9b3361

Ответ 1

Clone() также может вызывать исключение Out of memory, когда координаты, указанные в Rectangle, находятся за пределами растрового изображения. Он не будет автоматически скопировать их для вас.

Ответ 2

Я обнаружил, что использовал Image.Clone для обрезки растрового изображения, а ширина занимала урожай вне границ исходного изображения. Это вызывает ошибку "Ошибка в памяти". Кажется немного странным, но может быть известно.

Ответ 3

Я тоже получил это, когда попытался использовать метод Clone() для изменения формата изображения растрового изображения. Если используется память, я пытался преобразовать растровое изображение 24 бит/с в 8-битный индексированный формат, наивно надеясь, что класс Bitmap волшебным образом обработает создание палитры и так далее. Очевидно, что нет: -/

Ответ 4

Это досягаемость, но я часто обнаружил, что если вы снимаете изображения с диска, лучше скопировать их в новое растровое изображение и удалить изображение с привязкой к диску. При этом я видел значительное улучшение потребления памяти.

Дэйв М. тоже на деньги... убедитесь, что покончили.

Ответ 5

Убедитесь, что вы правильно вызываете .Dispose() на своих изображениях, иначе неуправляемые ресурсы не будут освобождены. Интересно, сколько изображений вы на самом деле создаете здесь - сотни? Тысячи?

Ответ 6

Я изо всех сил пытался понять это недавно - ответы выше верны. Ключом к решению этой проблемы является обеспечение того, чтобы прямоугольник фактически находился в границах изображения. См. Пример того, как я это решил.

Вкратце, проверено, была ли клонированная область вне области изображения.

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