2008-10-13 14 views
41

Warum erhalte ich eine Ausnahme wegen zu wenig Speicher?C# Image.Clone Nicht genügend Speicher Ausnahme

So stirbt dies in C# auf das erste Mal durch:

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

Wo splitBitmaps ist eine Liste <BitMap> Das funktioniert aber in VB für mindestens 4 Wiederholungen:

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

Wo arlSplitBitmaps ist eine einfache Array-Liste. (Und ja, ich habe Arraylist in C# versucht)

Dies ist fullsection:

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 ist ein Bitmap durch die Art und Weise.

Ich kann keine nützliche Antworten auf dem Intarweb finden, vor allem nicht, warum es in VB gut funktioniert.

Update:

Ich fand tatsächlich einen Grund (Art) für diesen Arbeits aber vergessen, es zu veröffentlichen. Es hat damit zu tun, das Bild in eine Bitmap zu konvertieren, anstatt nur das rohe Bild zu klonen, wenn ich mich daran erinnere.

Antwort

2

Stellen Sie sicher, dass Sie anrufen .Dispose() richtig auf Ihre Bilder, sonst nicht verwalteten Ressourcen nicht bis befreit werden. Ich frage mich, wie viele Bilder du hier tatsächlich machst - Hunderte? Tausende?

+1

Zweifel, es ist Speicher, sprengt das erste Mal durch. –

+0

Yeah Bitmap .Dispose hat nach meiner Erfahrung keine Auswirkungen auf diese OOM-Ausnahmen. –

3

Dies ist eine Reichweite, aber ich habe oft festgestellt, dass, wenn die Bilder direkt von der Festplatte ziehen, dass es besser ist, sie auf eine neue Bitmap zu kopieren und das scheiben gebunden Bildes entsorgen. Ich habe dabei eine große Verbesserung beim Speicherverbrauch gesehen.

Dave M. ist auch auf dem Geld ... stellen Sie sicher, wenn Sie fertig sind.

142

Clone() kann auch ein nicht genügend Arbeitsspeicher Ausnahme aus, wenn die in dem Rechteck angegebenen Koordinaten außerhalb der Grenzen des Bitmap sind. Es wird sie nicht automatisch für Sie abschneiden.

+25

Kam hier von der Straße von Google und dies beantwortet 100% meine Frage. – brian

+1

Das war die Antwort für mich auch :-) – JTech

+6

Nur eine kurze Anmerkung, falls es nicht offensichtlich ist (es war nicht zu mir zuerst): die Breite und die Höhe Parameter des Rechteckkonstruktors stellen das _area_ des Rechtecks ​​dar Sie wollen, nicht die unteren rechten Coords. Ex. Wenn Sie bei einem 100x100-Bild das Rechteck (15,10) auf (100,100) setzen möchten, benötigen Sie ein neues Rechteck (15, 10, 85, 90). Breite = Bildbreite-x (100-15 = 85), Höhe = Bildhöhe-y (100-10 = 90). 'Rectangle (15,10,100,100)' gibt Ihnen eine Ausnahme wegen zu wenig Speicher. – hawkke

4

Ich habe auch dies, wenn ich die Clone() -Methode verwendet versucht, das Pixel-Format einer Bitmap zu ändern. Wenn der Speicher dient, habe ich versucht, eine 24-Bit-Bitmap in ein indiziertes 8-Bit-Format zu konvertieren, naiv, in der Hoffnung, dass die Bitmap-Klasse die Palettenerstellung magisch handhaben würde und so weiter. Offensichtlich nicht: -/

+1

Für mich war dies ein Problem zwischen Windows 2003 Server und Windows 7 oder Windows 2008 Server. Klonen mit einigen PixelFormats schlägt auf Windows 2003 fehl. – CrnaStena

+0

Das war auch mein Problem. Ich klonte aus einem unübertroffenen Pixelformat. – allen1

6

Ich fand, dass ich wurde mit Image.Clone eine Bitmap zu beschneiden und die Breite nahm die Ernte außerhalb der Grenzen des ursprünglichen Bildes. Dies führt zu einem nicht ausreichenden Speicherfehler. Scheint ein bisschen seltsam, aber kann es wissen.

+0

Das war auch mein Problem, eine Koordinate von -1 wurde von einer Nummernschilddetektionsdll zurückgegeben. – SteveCav

3

Ich hatte Mühe, dies vor kurzem herauszufinden - die obigen Antworten sind richtig. Um dieses Problem zu lösen, müssen Sie sicherstellen, dass das Rechteck tatsächlich innerhalb der Grenzen des Bildes liegt. Siehe Beispiel, wie ich das gelöst habe.

In Kürze, überprüft, ob der Bereich, der geklont wurde, außerhalb des Bereichs des Bildes war.

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); 
+0

Es funktioniert für mich. –

+0

genial froh zu helfen – dellyjm

+0

Vielen Dank. Als Referenz können Sie einfach die Methode 'Intersect' verwenden, anstatt die Berechnungen selbst durchzuführen:' rect.Intersect (new Rectangle (0, 0, localImage.Width, localImage.Height)); ':) –

Verwandte Themen