Как избежать растрового изображения из памяти при работе с очень большим изображением, например: 10.000.000 пикселей и выше
В настоящее время я работаю над системой, которая загружает очень большое изображение с минимальной шириной x высотой> = 10.000.000 пикселей.
Но соотношение загружаемого изображения пользователя обычно не соответствует нашему соотношению требований, поэтому я должен обрезать его до правильного соотношения, но при использовании растрового изображения System.Drawing для обрезки я всегда получал исключение SytemOutOfMemory.
Я пробовал Bitmap.Clone и Graphic.DrawImage с правильным RectangleF, но не повезло.
Есть ли в любом случае сделать это без получения исключения из вне памяти или есть какие-либо альтернативы библиотеке System.Drawing для легкого выполнения этой задачи?
Мой код для загрузки изображения из файла загрузки пользователя:
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);
}
И функция 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[]));
}
}