Ответ 1
Clone() также может вызывать исключение Out of memory, когда координаты, указанные в Rectangle, находятся за пределами растрового изображения. Он не будет автоматически скопировать их для вас.
Почему я получаю исключение из памяти?
Таким образом, это первый раз умирает в С# через:
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:
Я действительно нашел причину (вроде) для этой работы, но забыл ее опубликовать. Это связано с преобразованием изображения в растровое изображение вместо того, чтобы просто клонировать исходное изображение, если я помню.
Clone() также может вызывать исключение Out of memory, когда координаты, указанные в Rectangle, находятся за пределами растрового изображения. Он не будет автоматически скопировать их для вас.
Я обнаружил, что использовал Image.Clone для обрезки растрового изображения, а ширина занимала урожай вне границ исходного изображения. Это вызывает ошибку "Ошибка в памяти". Кажется немного странным, но может быть известно.
Я тоже получил это, когда попытался использовать метод Clone() для изменения формата изображения растрового изображения. Если используется память, я пытался преобразовать растровое изображение 24 бит/с в 8-битный индексированный формат, наивно надеясь, что класс Bitmap волшебным образом обработает создание палитры и так далее. Очевидно, что нет: -/
Это досягаемость, но я часто обнаружил, что если вы снимаете изображения с диска, лучше скопировать их в новое растровое изображение и удалить изображение с привязкой к диску. При этом я видел значительное улучшение потребления памяти.
Дэйв М. тоже на деньги... убедитесь, что покончили.
Убедитесь, что вы правильно вызываете .Dispose() на своих изображениях, иначе неуправляемые ресурсы не будут освобождены. Интересно, сколько изображений вы на самом деле создаете здесь - сотни? Тысячи?
Я изо всех сил пытался понять это недавно - ответы выше верны. Ключом к решению этой проблемы является обеспечение того, чтобы прямоугольник фактически находился в границах изображения. См. Пример того, как я это решил.
Вкратце, проверено, была ли клонированная область вне области изображения.
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);