Ho una situazione in cui è necessario ridimensionare un numero elevato di immagini. Queste immagini sono attualmente archiviate come file .jpg sul file system, ma mi aspetto di avere byte [] in memoria più avanti nel progetto. La dimensione dell'immagine sorgente è variabile, ma l'output dovrebbe essere di 3 dimensioni predeterminate differenti. I rapporti di aspetto dovrebbero essere preservati, riempendo l'immagine originale con uno spazio bianco (ad esempio, un'immagine molto alta verrà ridimensionata per adattarsi alle dimensioni dell'immagine target quadrata, con ampie aree di bianco a sinistra ea destra).Ridimensionamento delle prestazioni delle immagini: System.Drawing vs System.Windows.Media
Inizialmente ho creato il progetto con targeting per .NET 2.0 e utilizzando le classi System.Drawing per eseguire il caricamento/ridimensionamento/salvataggio. relativo codice comprende:
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);
ho voluto porto questo progetto NET 3.5, quindi provato utilizzando le classi System.Windows.Media per eseguire la stessa funzione. L'ho fatto funzionare, tuttavia le prestazioni sono terribili; il tempo di elaborazione per immagine è di circa 50 volte più lungo. La maggior parte del tempo viene impiegata per caricare l'immagine. Il codice rilevante include:
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);
Sto facendo qualcosa di sbagliato qui, per prendere così tanto tempo? Ho provato a utilizzare solo il costruttore su BitmapImage che prende un URI, lo stesso problema di prestazioni. Qualcuno ha fatto qualcosa di simile prima, sai se c'è un modo più performante per farlo? O ho solo bisogno di usare ancora System.Drawing? Grazie!
Grazie per il suggerimento! – Jan