Pergunta

Tenho um problema com a memória quando estou tentando carregar algumas imagens em uma caixa de imagem.

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`
Foi útil?

Solução

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

Mau. Você está carregando a imagem do arquivo, verificando se o resultado é nulo ... então carregando -o novamente em um novo resultado para que você possa descartá -lo. Embora a última parte seja boba, não é prejudicial. A primeira parte é, no entanto, como o resultante Image nunca é descartado adequadamente (se/quando o GC o coleta, o finalizador no Image modelo deve descarte os recursos não gerenciados, mas isso não é uma coisa sábia para confiar).

Aliás, Image.FromFile nunca voltará null. Se não conseguir ler a imagem, ele jogará um OutOfMemoryException.

O código também parece não fazer nada, já que não há else bloco e nada significativo é feito no if quadra.

Meu palpite é que o seu OutOfMemoryException está proveniente do fato de que um ou mais dos arquivos nesse diretório são armazenados em um formato de imagem corrompido ou não suportado, ou não é uma imagem.

Tente substituir o código em seu foreach com isso:

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

Outras dicas

A caixa de imagens mantém internamente uma referência ao bitmap que você coloca nela. A menos que você se livre da caixa de figuras, ela está mantendo uma referência a todo o bitmap que você carrega nela.

Algo que você deve considerar que, independentemente do tipo de imagem armazenada no disco, quando você a abrir para exibição, a imagem se tornará um bitmap e exige 4 bytes por pixel exibido.

Seu código parece sugerir uma tentativa de uma operação de miniatura. Na verdade, você está carregando 70 arquivos na memória e, independentemente do tamanho da tela, na memória eles serão muito grandes.

Por exemplo, digamos que você tenha 70 JPEGs com profundidade de cor de 32 bits e diga 1920x1080 pixels de tamanho. Seu requisito de memória para carregar tantas imagens de uma vez é:

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

E essa é uma estimativa bastante baixa.

Você pode considerar carregar muito menos fotos ou tentar uma solução real de miniatura.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top