Zeit auf einem System arbeite ich, dass ein sehr großes Bild zu laden, mit minimaler Breite x heigh> = 10.000.000 Pixel.Wie Bitmap aus dem Speicher zu vermeiden, wenn für dh auf sehr großes Bild Arbeits: 10.000.000 Pixel und über
Aber das Verhältnis der Upload-Bild des Benutzers nicht in der Regel unsere Anforderungsquote entsprechen, so muss ich es auf das richtige Verhältnis zuschneiden, aber wenn System.Drawing Bitmap zu beschneiden, ich habe immer SytemOutOfMemory Ausnahme.
Ich habe Bitmap.Clone und Graphic.DrawImage mit korrekten RectangleF versuchen, aber ohne Glück.
Gibt es sowieso, dies zu tun, ohne die OutOfMemory Ausnahme zu bekommen oder gibt es Alternativen zu System.Drawing Bibliothek diese Aufgabe leicht zu erledigen?
Mein Code, um das Bild von Benutzer-Upload-Datei zu laden:
var fileBinary = new byte[stream.Length];
stream.Read(fileBinary, 0, fileBinary.Length);
stream.Position = 0;
var fileExtension = Path.GetExtension(fileName);
using (Image image = Image.FromStream(stream, false, false))
{
//validation and check ratio
CropImage(image, PORTRAIT_RATIO, fileExtension);
}
Und die CropImage Funktion:
//Crop Image from center with predefine ratio
private byte[] CropImage(Image sourceImg, float ratio, string fileExtension)
var height = sourceImg.Height;
var width = sourceImg.Width;
var isPortrait = width < height;
RectangleF croppingRec = new RectangleF();
float positionX = 0;
float positionY = 0;
float cropHeight = (float)height;
float cropWidth = cropHeight * PORTRAIT_RATIO;
positionY = 0;
positionX = (width - cropWidth)/2;
if (cropWidth > width)
{
cropWidth = width;
cropHeight = cropWidth * (1/PORTRAIT_RATIO);
positionX = 0;
positionY = ((height - cropHeight)/2);
}
croppingRec.Width = cropWidth;
croppingRec.Height = cropHeight;
croppingRec.X = positionX;
croppingRec.Y = positionY;
Bitmap bmpImage = sourceImg as Bitmap;
Bitmap bmpCrop = bmpImage.Clone(croppingRec, bmpImage.PixelFormat);
bmpCrop.Save("D:/test" + fileExtension, ImageFormat.Jpeg);
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(bmpCrop, typeof(byte[]));
}
}
check out http://imageresizing.net/ – jle
haben Sie versucht, als '64bit' App mit speziellen Flag kompilieren, die Speicher Einschränkungen von der CLR entfernt (abgesehen von max 2GB für einzelne Liste Sammlung)? –
Tigran
10 Millionen Pixel sind normalerweise kein Problem, eine halbe Milliarde ist das theoretische Maximum, aber in einem 32-Bit-Prozess neigen Sie dazu, lange vorher zu fallen. In der Regel 25 Millionen, wenn Ihr Programm eine Weile läuft. Der wahrscheinlichste Fehler in Ihrem Code ist es, vergessen zu haben, Dispose() aufzurufen, es ist eine steinharte Voraussetzung, wenn Sie die Bitmap-Klasse verwenden und viel zu viele Programmierer vergessen es. Niemand kann Ihren Fehler sehen, wenn Sie Ihren Code nicht veröffentlichen. –