Pregunta

Tengo un problema sin memoria cuando estoy tratando de carga de un par de imágenes en un cuadro de imagen.

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

Solución

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

Bad. Va a cargar la imagen desde el archivo, la comprobación para ver si el resultado es nulo ... a continuación, volver a embarcarse en un nuevo resultado para que pueda deshacerse de él. Mientras que la última porción es tonto, no es perjudicial. La primera parte es, sin embargo, como el Image resultante nunca es desechado apropiadamente (si / cuando el GC lo recoge, el finalizador del tipo Image debe disponer de los recursos no administrados, pero esto no es una cosa sabia que depender de).

Por cierto, Image.FromFile no volverá null. Si no puede leer la imagen, entonces se generará un OutOfMemoryException.

El código también parece hacer nada, ya que no hay ningún bloque else y nada significativo se realiza en el bloque if.

Mi conjetura es que su OutOfMemoryException viene del hecho de que uno o más de los archivos de ese directorio se almacena en un formato de imagen dañada o no soportado , o no es una imagen en absoluto.

Trate de reemplazar el código en su foreach con esto:

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

Otros consejos

El cuadro de imagen tiene internamente una referencia al mapa de bits que se coloca en ella. A menos que deshacerse del cuadro de imagen, que está sosteniendo una referencia a cada mapa de bits se carga en él.

Algo que hay que tener en cuenta que, independientemente del tipo de imagen almacenada en el disco, cuando se abre para mostrar la imagen se convertirá en un mapa de bits y requieren 4 bytes por píxel mostrado.

Su código parece sugerir una tentativa en una operación en miniatura. Usted es, de hecho, la carga 70 archivos en la memoria e independientemente del tamaño de la pantalla, en la memoria van a ser muy grandes.

Por ejemplo digamos que usted tiene 70 imágenes JPEG en una profundidad de color de 32 bits y decir 1920x1080 píxeles de tamaño. Su requisito de memoria para cargar esa cantidad de imágenes a la vez entonces es:

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

Y eso es una estimación bastante baja.

Se podría considerar cargar muchas menos imágenes o tratando una solución thumbnailing real.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top