Wie vermeide ich Bitmap-Speichermangel, wenn ich ein sehr großes Bild bearbeite, z. B .: 10.000.000 Pixel und mehr

erzeit arbeite ich an einem System, das ein sehr großes Bild mit einer minimalen Breite x Höhe> = 10.000.000 Pixel läd

Aber das Verhältnis des Upload-Bildes des Benutzers stimmt normalerweise nicht mit unserem Anforderungsverhältnis überein, sodass ich es auf das richtige Verhältnis zuschneiden muss, aber wenn ich System.Drawing-Bitmap zum Zuschneiden verwende, habe ich immer die Ausnahme SytemOutOfMemory.

Ich habe versucht Bitmap.Clone und Graphic.DrawImage mit korrektem RectangleF, aber kein Glück.

Ist es irgendwie möglich, dies zu tun, ohne die Ausnahmebedingung outofmemory zu erhalten, oder gibt es Alternativen zur System.Drawing-Bibliothek, um diese Aufgabe einfach zu erledigen?

Mein Code zum Laden des Bildes aus der Benutzer-Upload-Datei:

    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[]));
    }

}

Antworten auf die Frage(4)

Ihre Antwort auf die Frage