Недостаточно памяти, несколько изображений в одном PictureBox

StackOverflow https://stackoverflow.com/questions/2449587

  •  20-09-2019
  •  | 
  •  

Вопрос

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

public void button2_Click(object sender, EventArgs e)
    {


        FolderBrowserDialog dialog = new FolderBrowserDialog();
        dialog.ShowDialog();
        string selected = dialog.SelectedPath;

        string[] imageFileList = Directory.GetFiles(selected);


        int iCtr = 0,zCtr = 0;
        foreach(string imageFile in imageFileList)
        {

            if (Image.FromFile(imageFile) != null)
            {
                Image.FromFile(imageFile).Dispose();
            }

            PictureBox eachPictureBox = new PictureBox();

            eachPictureBox.Size = new Size(100,100);
           // if (iCtr % 8 == 0)
            //{
             //   zCtr++;
              //  iCtr = 0;
            //}
            eachPictureBox.Location = new Point(iCtr * 100 + 1, 1);
            eachPictureBox.Image = Image.FromFile(imageFile);
            iCtr++;

            panel1.Controls.Add(eachPictureBox);

        }


    }`enter code here`
Это было полезно?

Решение

if (Image.FromFile(imageFile) != null)
{
    Image.FromFile(imageFile).Dispose();
}

Плохой.Вы загружаете изображение из файла, проверяете, является ли результат нулевым... затем снова загружаете его в новый результат, чтобы можно было его удалить.Хотя последняя часть глупа, она не вредна.Однако первая часть является результатом Image никогда не удаляется должным образом (если/когда сборщик мусора собирает его, финализатор на Image тип должен избавьтесь от неуправляемых ресурсов, но полагаться на это неразумно).

Кстати, Image.FromFile никогда не вернется null.Если он не может прочитать изображение, он выдаст ошибку OutOfMemoryException.

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

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

Попробуйте заменить код в вашем foreach с этим:

try
{
    Image image = Image.FromFile(imageFile);

    PictureBox eachPictureBox = new PictureBox();

    eachPictureBox.Size = new Size(100,100);

    eachPictureBox.Location = new Point(iCtr * 100 + 1, 1);
    eachPictureBox.Image = Image.FromFile(imageFile);
    iCtr++;

    panel1.Controls.Add(eachPictureBox);
}
catch(OutOfMemoryException) { } // skip the file

Другие советы

Внутри поля изображения содержится ссылка на растровое изображение, которое вы в него помещаете.Если вы не избавитесь от поля изображения, оно будет содержать ссылку на каждое растровое изображение, которое вы в него загружаете.

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

Кажется, ваш код предполагает попытку операции с миниатюрами.Вы по факту загружаете в память 70 файлов и независимо от размера дисплея, в памяти они будут очень большими.

Например, предположим, что у вас есть 70 изображений в формате JPEG с глубиной цвета 32 бита и размером, скажем, 1920x1080 пикселей.Ваши требования к памяти для одновременной загрузки такого количества изображений составляют:

 70 pics x 1920 pixels x 1080 pixels x 4 bytes/pixel = 580,608,000 bytes! 

И это довольно заниженная оценка.

Вы могли бы рассмотреть возможность загрузки гораздо меньшего количества изображений или попробовать настоящее решение для создания миниатюр.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top