Cómo evitar la falta de memoria de mapa de bits cuando se trabaja en una imagen muy grande, es decir, 10.000.000 de píxeles y superiores

Actualmente estoy trabajando en un sistema que carga una imagen muy grande, con un ancho mínimo x altura> = 10.000.000 de píxeles.

Pero la proporción de la imagen de carga del usuario generalmente no coincide con nuestra proporción requerida, por lo que tengo que recortarla a la proporción adecuada, pero cuando uso System.Drawing bitmap para recortarla, siempre tengo la excepción SytemOutOfMemory.

He intentado Bitmap.Clone y Graphic.DrawImage con RectangleF correcto pero no tuve suerte.

¿Hay alguna forma de hacer esto sin obtener la excepción de memoria o hay alguna alternativa a la biblioteca System.Drawing para realizar esta tarea fácilmente?

Mi código para cargar la imagen del archivo de carga del usuario:

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

Y la función CropImage:

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

}

Respuestas a la pregunta(2)

Su respuesta a la pregunta