C # Image.Clone Out of Memory Exception - PullRequest
47 голосов
/ 14 октября 2008

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

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

splitBitmaps.Add (requiredImage.Clone (rectDimensions, requiredImage.PixelFormat));

Где splitBitmaps - это список НО это работает в VB как минимум 4 итерации:

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

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

Это полный раздел:

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

}

requiredImage - это растровое изображение.

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

Обновление:

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

Ответы [ 6 ]

154 голосов
/ 17 марта 2009

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

8 голосов
/ 07 февраля 2014

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

5 голосов
/ 22 января 2010

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

4 голосов
/ 13 марта 2015

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

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

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);
4 голосов
/ 14 октября 2008

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

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

3 голосов
/ 14 октября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...