Domanda

Ho un problema con la memoria quando sto cercando di carico alcune immagini in un unico 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`
È stato utile?

Soluzione

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

Bad. Si sta caricando l'immagine dal file, il controllo per vedere se il risultato è nullo ... poi caricarlo di nuovo in un nuovo risultato in modo da poter disporre di esso. Mentre l'ultima parte è stupido, non è dannoso. La prima parte è, tuttavia, come la Image risultante viene mai adeguatamente smaltiti (se / quando il GC raccoglie esso, il finalizzatore del tipo Image dovrebbe disporre delle risorse non gestite, ma questo non è un cosa saggia da fare affidamento su).

Per inciso, Image.FromFile non tornerà mai null. Se non riuscite a vedere il, allora sarà lanciare un OutOfMemoryException.

Il codice sembra anche non fare nulla, dal momento che non c'è alcun blocco else e niente significativo viene fatto nel blocco if.

La mia ipotesi è che il vostro OutOfMemoryException è venuta dal fatto che uno o più dei file in quella directory è memorizzato in un formato di immagine danneggiato o non supportato , o non è un immagine a tutti.

Provare a sostituire il codice nel tuo foreach con questo:

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

Altri suggerimenti

La casella di immagine contiene internamente un riferimento al bitmap che si inserisce in esso. A meno che non si sbarazzarsi della casella di immagine, sono in possesso di un riferimento ad ogni bitmap si carica in esso.

Qualcosa si deve considerare che, indipendentemente dal tipo di immagine memorizzato su disco, quando lo si apre per la visualizzazione l'immagine diventerà una bitmap e richiedono 4 byte per pixel visualizzato.

Il tuo codice sembra suggerire un tentativo di un'operazione di miniature. Sei in realtà carico di 70 file in memoria e, indipendentemente dalla dimensione del display, nella memoria che sarà molto grande.

Per esempio supponiamo di avere 70 file JPEG a profondità di colore a 32 bit e dire 1920x1080 pixel di dimensione. Il vostro requisito di memoria per caricare che molte immagini in una sola volta, allora è:

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

E questa è una stima abbastanza basso.

Si potrebbe prendere in considerazione il caricamento di molte meno immagini o cercando per una soluzione miniature reale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top