Eccezione C # Image.Clone Out of Memory

Perché ricevo un’eccezione di memoria insufficiente?

Quindi questo muore in C # per la prima volta attraverso:

splitBitmaps.Add (neededImage.Clone (rectDimensions, neededImage.PixelFormat));

Dove splitBitmaps è una lista MA questo funziona in VB per almeno 4 iterazioni:

arlSplitBitmaps.Add (Image.Clone (rectDimensions, Image.PixelFormat))

Dove arlSplitBitmaps è un semplice elenco di array. (E sì, ho provato l’arraylist in c #)

Questa è la sezione intera:

for (Int32 splitIndex = 0; splitIndex <= numberOfResultingImages - 1; splitIndex++) { Rectangle rectDimensions; if (splitIndex < numberOfResultingImages - 1) { rectDimensions = new Rectangle(splitImageWidth * splitIndex, 0, splitImageWidth, splitImageHeight); } else { rectDimensions = new Rectangle(splitImageWidth * splitIndex, 0, sourceImageWidth - (splitImageWidth * splitIndex), splitImageHeight); } splitBitmaps.Add(neededImage.Clone(rectDimensions, neededImage.PixelFormat)); 

}

neededImage è a tutti gli effetti una bitmap.

Non riesco a trovare nessuna risposta utile su intarweb, soprattutto non perché funziona correttamente in VB.

Aggiornare:

In realtà ho trovato una ragione (sorta di) per questo lavoro, ma ho dimenticato di postarlo. Ha a che fare con la conversione dell’immagine in un bitmap invece di cercare di clonare l’immagine grezza se ricordo.

Clone () può anche lanciare un’eccezione di memoria esaurita quando le coordinate specificate nel rettangolo sono al di fuori dei limiti della bitmap. Non li ritaglierà automaticamente per te.

Ho scoperto che stavo usando Image.Clone per ritagliare una bitmap e la larghezza ha preso il ritaglio fuori dai limiti dell’immagine originale. Ciò provoca un errore di memoria insufficiente. Sembra un po ‘strano, ma può essere interessante sapere.

Ho capito anche questo quando ho provato ad usare il metodo Clone () per cambiare il formato pixel di una bitmap. Se la memoria serve, stavo cercando di convertire una bitmap da 24 bpp in un formato indicizzato a 8 bit, sperando ingenuamente che la class Bitmap potesse gestire magicamente la creazione della palette e così via. Ovviamente no :-/

Questa è una portata, ma ho spesso riscontrato che se si tirano le immagini direttamente dal disco è meglio copiarle su una nuova bitmap e smaltire l’immagine legata al disco. Ho notato grandi miglioramenti nel consumo di memoria quando lo faccio.

Anche Dave M. ha i soldi … assicurati di smaltirlo una volta finito.

Ho faticato a capirlo di recente – le risposte sopra sono corrette. La chiave per risolvere questo problema è assicurarsi che il rettangolo si trovi effettivamente entro i limiti dell’immagine. Guarda l’esempio di come ho risolto questo.

In poche parole, controlla se l’area che stava per essere clonata era fuori dall’area dell’immagine.

 int totalWidth = rect.Left + rect.Width; //think -the same as Right property int allowableWidth = localImage.Width - rect.Left; int finalWidth = 0; if (totalWidth > allowableWidth){ finalWidth = allowableWidth; } else { finalWidth = totalWidth; } rect.Width = finalWidth; int totalHeight = rect.Top + rect.Height; //think same as Bottom property int allowableHeight = localImage.Height - rect.Top; int finalHeight = 0; if (totalHeight > allowableHeight){ finalHeight = allowableHeight; } else { finalHeight = totalHeight; } rect.Height = finalHeight; cropped = ((Bitmap)localImage).Clone(rect, System.Drawing.Imaging.PixelFormat.DontCare); 

Assicurati di chiamare correttamente .Dispose () sulle tue immagini, altrimenti le risorse non gestite non verranno liberate. Mi chiedo quante immagini stai effettivamente creando qui – centinaia? Migliaia?