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