我遇到了需要调整大量图像大小的情况。这些图像目前在文件系统上存储为 .jpg 文件,但我希望稍后在项目中内存中只有 byte[] 。源图像大小是可变的,但输出应该是 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's 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 吗?谢谢!