Недостаточно памяти для нескольких изображений в одной картинке - PullRequest
1 голос
/ 15 марта 2010

У меня проблема с нехваткой памяти, когда я пытаюсь загрузить несколько изображений в один 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`

Ответы [ 3 ]

1 голос
/ 15 марта 2010

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

1 голос
/ 15 марта 2010
if (Image.FromFile(imageFile) != null)
{
    Image.FromFile(imageFile).Dispose();
}

Bad. Вы загружаете изображение из файла, проверяете, является ли результат нулевым ... затем загружаете его снова в новый результат, чтобы вы могли утилизировать его. Хотя последняя часть глупа, это не вредно. Первая часть, однако, так как результирующее Image никогда не удаляется должным образом (если / когда GC собирает его, финализатор типа 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
0 голосов
/ 15 марта 2010

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

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

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

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

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

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

...