У меня есть ситуация, когда мне нужно изменить размер большого количества изображений. Эти изображения хранятся как .jpg файлы в файловой системе в настоящее время, но я ожидаю, что просто будет байтом [] в памяти позже в проекте. Размер исходного изображения является переменным, но выход должен быть 3 разных заранее определенных размера. Соотношение сторон должно быть сохранено, добавив исходное изображение в пробел (то есть, очень высокое изображение будет изменено в соответствии с размером квадратного целевого изображения с большими областями белого слева и справа).
Сначала я построил проект, ориентированный на .NET 2.0, и используя классы System.Drawing для выполнения загрузки/изменения размера/сохранения. Соответствующий код включает:
original = Image.FromFile(inputFile); //NOTE: Reused for each of the 3 target sizes
Bitmap resized = new Bitmap(size, size);
//Draw the image to a new image of the intended size
Graphics g = Graphics.FromImage(resized);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.Clear(Color.White);
g.DrawImage(original, center - width / 2f, center - height / 2f, width, height);
g.Dispose();
//Save the new image to the output path
resized.Save(outputFile, ImageFormat.Jpeg);
Я хотел перенести этот проект на .NET 3.5, поэтому попробовал использовать классы System.Windows.Media для выполнения той же функции. Я получил его работу, однако производительность ужасна; время обработки изображения составляет примерно 50 раз. Подавляющее большинство времени тратится на загрузку изображения. Соответствующий код включает:
BitmapImage original = new BitmapImage(); //Again, reused for each of the 3 target sizes
original.BeginInit();
original.StreamSource = new MemoryStream(imageData); //imageData is a byte[] of the data loaded from a FileStream
original.CreateOptions = BitmapCreateOptions.None;
original.CacheOption = BitmapCacheOption.Default;
original.EndInit(); //Here where the vast majority of the time is spent
original.Freeze();
// Target Rect for the resize operation
Rect rect = new Rect(center - width / 2d, center - height / 2d, width, height);
// Create a DrawingVisual/Context to render with
DrawingVisual drawingVisual = new DrawingVisual();
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
{
drawingContext.DrawImage(original, rect);
}
// Use RenderTargetBitmap to resize the original image
RenderTargetBitmap resizedImage = new RenderTargetBitmap(
size, size, // Resized dimensions
96, 96, // Default DPI values
PixelFormats.Default); // Default pixel format
resizedImage.Render(drawingVisual);
// Encode the image using the original format and save the modified image
SaveImageData(resizedImage, outputFile);
Я делаю что-то не так здесь, чтобы уделить столько времени? Я пробовал просто использовать конструктор в BitmapImage, который принимает URI, такая же проблема с производительностью. Кто-нибудь сделал что-нибудь подобное раньше, узнайте, есть ли более эффективный способ сделать это? Или мне еще нужно будет использовать System.Drawing? Спасибо!