Недостаточно памяти Image.FromFile - PullRequest
17 голосов
/ 03 октября 2010

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

if (File.Exists(photoURI))
{
    FileStream fs = new FileStream(photoURI, FileMode.Open, FileAccess.Read);
    Image img = Image.FromStream(fs);
    fs.Close();
}

Ответы [ 6 ]

29 голосов
/ 03 октября 2010

В документации Image.FromFile, OutOfMemoryException может быть выброшено, если:

Файл не имеет допустимого формата изображения.-или-

GDI + не поддерживает пиксельный формат файла.

Проверьте формат изображения.

Также, если вы хотите закрыть поток справапосле загрузки изображения вы должны сделать копию изображения.Взгляните здесь .GDI + должен держать поток открытым в течение всего времени жизни изображения.

7 голосов
/ 03 октября 2010

Первая ошибка:

if (File.Exists())

Файловая система является нестабильной, поэтому доступ к вашему файлу может меняться между строкой с вашим условием if и следующей строкой. Кроме того, File.Exists () может возвращать значение true, но FileStream все равно может выдать исключение, если у вас нет прав доступа к файлу или он уже заблокирован.

Вместо этого, правильный способ справиться с этим - использовать блок try / catch. Вместо этого посвятите время разработки обработчику исключений, потому что вы все равно должны писать этот код.

Вторая ошибка:

fs.Close();

Эта строка должна находиться внутри блока finally, иначе у вас есть возможность оставить открытые дескрипторы файлов. Обычно я рекомендую блок using, чтобы обеспечить правильное размещение ресурсов такого типа, но, поскольку вам уже нужен try / catch, вы можете использовать вместо этого код:

Image img = null;
FileStream fs = null;
try
{
    fs = new FileStream(photoURI, FileMode.Open, FileAccess.Read);    
    img = Image.FromStream(fs);    
}
finally
{
    fs.Close();
}
3 голосов
/ 27 ноября 2011

Вы не можете использовать Image.FromStream для своего файла, вместо этого вы должны декодировать файл, используя TiffBitmapDecoder.Пример кода из MSDN:

// Open a Stream and decode a TIFF image
Stream imageStreamSource = new FileStream("tulipfarm.tif", FileMode.Open, FileAccess.Read, FileShare.Read);
TiffBitmapDecoder decoder = new TiffBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource bitmapSource = decoder.Frames[0];

// Draw the Image
Image myImage = new Image();
myImage.Source = bitmapSource;
myImage.Stretch = Stretch.None;
myImage.Margin = new Thickness(20);
2 голосов
/ 05 августа 2011

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

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

proc = Process.GetCurrentProcess();
Console.WriteLine("Memory Usage" + proc.PrivateMemorySize64);
1 голос
/ 05 июля 2013

См. этот ответ от Ганса Пассанта:

GDI + был написан довольно давно, прежде чем появился .NET.Оболочка SDK для него была написана на C ++.Чтобы сохранить его совместимость, он не может использовать исключения.Об ошибках сообщалось с кодами ошибок.Это никогда не масштабируется, GDI + имеет только 20 кодов ошибок.Это не так много для такого большого куска кода.

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

0 голосов
/ 04 декабря 2014

Снимите отметку Encrypt contents to secure data в свойствах файла - это решило проблему для меня.

enter image description here

...