У меня есть программа для загрузки и обрезки изображений, которая создает миниатюры, и иногда я получаю исключение Out Of Memory в следующей строке:

Dim bm As Bitmap = System.Drawing.Image.FromFile(imageFile)

Возникновение ошибки крошечное и очень редкое, но я всегда хочу знать, что может быть причиной ее. Переменная imageFile - это просто Server.MapPath пути к изображению.

Мне было любопытно, сталкивался ли кто-нибудь с этой проблемой раньше и были ли у них идеи, что могло бы ее вызвать? Возможно, дело в размере изображения?

Я могу опубликовать код, если необходимо, и любую имеющуюся у меня вспомогательную информацию, но я хотел бы услышать мнение людей по этому поводу.

45
dooburt 10 Июл 2009 в 13:27

12 ответов

Лучший ответ

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

Вы удаляете все свои растровые изображения после того, как закончите с ними? Повторяется ли это для одного изображения?

47
Jon Skeet 10 Июл 2009 в 09:30

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

using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
   using (Image original = Image.FromStream(fs))
   {
      ...

Использование явного Dispose(), оператора using() или установка значения null на растровом изображении не решает проблему с Image.FromFile.

Поэтому, если ваше приложение запускается какое-то время и открывает много файлов, подумайте об использовании вместо него Image.FromStream().

34
Ian Mercer 23 Апр 2012 в 17:03

Сегодня я столкнулся с той же проблемой при создании изображений эскизов для папки, полной изображений. Оказывается, "Out Of Memory" каждый раз происходил точно в один и тот же момент. Когда я заглянул в папку с изображениями, которые нужно преобразовать, я обнаружил, что файл, который создавал проблему, был thumbs.db. Я добавил код, чтобы убедиться, что конвертируются только файлы изображений, и проблема решена.

Мой код в основном

For Each imageFile as FileInfo in fileList
If imageFile.Extension = ".jpg" Or imageFile.Extension = ".gif" Then
    ...proceed with the conversion
End If
Next

Надеюсь это поможет.

7
sjngm 19 Авг 2011 в 07:47

Также вы можете открыть его в режиме чтения (если вы хотите использовать его в двух местах одновременно)

 public Image OpenImage(string previewFile)
        {
            FileStream fs = new FileStream(previewFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            return Image.FromStream(fs);
        }
3
Avram 31 Авг 2010 в 08:37

Также проверьте, не открывали ли вы тот же файл в другом месте. Видимо, когда вы открываете файл дважды (даже с File.Open ()), тоже выдается OutOfMemoryException ...

2
pinus.acer 23 Окт 2014 в 10:57

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

2
David Grund 19 Май 2019 в 02:04

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

private static Image resizeImage(Image imgToResize, Size size)
{
   int sourceWidth = imgToResize.Width;
   int sourceHeight = imgToResize.Height;

   float nPercent = 0;
   float nPercentW = 0;
   float nPercentH = 0;

   nPercentW = ((float)size.Width / (float)sourceWidth);
   nPercentH = ((float)size.Height / (float)sourceHeight);

   if (nPercentH < nPercentW)
      nPercent = nPercentH;
   else
      nPercent = nPercentW;

   int destWidth = (int)(sourceWidth * nPercent);
   int destHeight = (int)(sourceHeight * nPercent);

   Bitmap b = new Bitmap(destWidth, destHeight);
   Graphics g = Graphics.FromImage((Image)b);
   g.InterpolationMode = InterpolationMode.HighQualityBicubic;

   g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
   g.Dispose();

   return (Image)b;
}

А затем этот код для урожая ...

private static Image cropImage(Image img, Rectangle cropArea)
{
   Bitmap bmpImage = new Bitmap(img);
   Bitmap bmpCrop = bmpImage.Clone(cropArea,
   bmpImage.PixelFormat);
   return (Image)(bmpCrop);
}

Тогда вот как я назвал приведенный выше код ...

Image img = Image.FromFile(@"C:\Users\****\Pictures\image.jpg");
img = ImageHandler.ResizeImage(img, new Size(400, 300));
img = ImageHandler.CropImage(img, new Rectangle(0, 25, 400, 250));
long quality = 90;

У меня постоянно возникали ошибки в части кадрирования, изменение размера работало нормально!

Оказывается, то, что происходило внутри изменения размера, вызывало ошибки в функции кадрирования. В результате вычислений с измененным размером фактические размеры изображения оказались равными 399, а не 400, которые я передал.

Итак, когда я передал 400 в качестве аргумента для кадрирования, он пытался обрезать изображение шириной 399 пикселей с BMP шириной 400 пикселей, и это выдало ошибку нехватки памяти!

Большая часть приведенного выше кода была найдена на http: / /www.switchonthecode.com/tutorials/csharp-tutorial-image-editing-saving-cropping-and-resizing

1
jcreamer898 29 Мар 2011 в 19:20

Если изображение является значком, тогда требуется другая обработка загрузки, как в следующей функции:

public static Image loadImage(string imagePath)
    {
        Image loadedImage = null;
        if (!File.Exists(imagePath)) return loadedImage;
        try
        {
            FileInfo fileInfo = new FileInfo(imagePath);
            if (fileInfo.Extension.Equals(".jpg") || fileInfo.Extension.Equals(".jpeg") ||
               fileInfo.Extension.Equals(".bmp") || fileInfo.Extension.Equals(".png") ||
               fileInfo.Extension.Equals(".gif"))
            {
                loadedImage = Image.FromFile(imagePath);
            }
            else if (fileInfo.Extension.Equals(".ico"))
            {
                Bitmap aBitmap = Bitmap.FromHicon(new
                                           Icon(imagePath, new Size(200, 200)).Handle);
                loadedImage = ImageFuncs.ResizeImage(aBitmap, new Size(30, 30));
            }
        }
        catch (Exception eLocal)
        {
            MessageBox.Show(imagePath + " loading error: " + eLocal.Message);
        }
        return loadedImage;
    }
1
IrinaL 24 Мар 2014 в 07:42

У меня была такая же проблема с утилитой, которую я написал для преобразования TIFF (ов) в PDF (ы). Часто я получал ошибку «нехватка памяти» в той же строке, что и вы.

System.Drawing.Image.FromFile(imageFile)

Затем я обнаружил, что ошибка возникает только тогда, когда расширение файла было «.tiff», и работала нормально после того, как я переименовал его с расширением «.tif».

1
Jeff Chapin 24 Июн 2014 в 01:05

У меня такая же проблема с пакетной обработкой файлов Tiff. Большинство файлов не генерируют исключение, но некоторые файлы генерируют исключение «Недостаточно памяти» в ASP.NET 4.0. Я использовал двоичные данные, чтобы выяснить, почему только для нескольких файлов и из одной папки. Это не может быть проблемой разрешения для учетной записи ASP.NET ASPNET или NETWORK SERVICE, потому что другие файлы являются рабочим файлом.

Я открыл класс iTextSharp.text.Image и обнаружил, что есть много перегруженных методов для GetInstance (). Я решил свою проблему, используя следующий код: примечание: блок catch будет запускаться для проблемных файлов.

                iTextSharp.text.Image image = null;
            try
                {
                    var imgStream = GetImageStream(path);
                     image = iTextSharp.text.Image.GetInstance(imgStream);
                }
                catch {
                    iTextSharp.text.pdf.RandomAccessFileOrArray ra = null;
                    ra = new iTextSharp.text.pdf.RandomAccessFileOrArray(path);
                    image = iTextSharp.text.pdf.codec.TiffImage.GetTiffImage(ra, 1);

                    if (ra != null)
                        ra.Close();

                }
0
Nilesh Hirpara 31 Окт 2013 в 18:42

Если вы используете IIS, попробуйте перезапустить пул приложений. Это решило для меня аналогичную ошибку загрузки изображения «Недостаточно памяти».

0
Rich 20 Май 2019 в 15:32

У меня была такая же проблема, прежде чем искать другое место в коде, я хотел убедиться, могу ли я открыть изображение с помощью любого средства просмотра изображений, и выяснил, что изображение повреждено / повреждено, хотя это файл .PNG размером 1 КБ. Добавлено новое изображение в том же месте, затем оно сработало.

1
Kiran Modini 27 Дек 2017 в 16:39