Képek átméretezéséhez lehet használni az Image.GetThumbnailImage metódust, aminek az egyik baja, hogy nem túl szép az átméretezett eredmény, a másik, hogy vadul képes ExternalExceptionöket és OutOfMemoryExceptionöket dobálni, ha nem tetszik neki az eredeti kép. Van más lehetőség is.
Használhatjuk például a Graphics.DrawImage metódust, ráadásul a Graphics objektumnak még az InterpolationMode tulajdonságát is be tudjuk állítani:
private static Image ResizeImage( Image originalImage, int maxWidth, int maxHeight )
{
if( originalImage.Width == maxWidth && originalImage.Height == maxHeight )
{
return originalImage;
}
float ratio;
float ratioWidth;
float ratioHeight;
ratioWidth = (float) maxWidth / (float) originalImage.Width;
ratioHeight = (float) maxHeight / (float) originalImage.Height;
ratio = ratioHeight < ratioWidth ? ratioHeight : ratioWidth;
int destWidth = (int) ( originalImage.Width * ratio );
int destHeight = (int) ( originalImage.Height * ratio );
Bitmap bitmap = new Bitmap( destWidth, destHeight );
using( Graphics g = Graphics.FromImage( (Image) bitmap ) )
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage( originalImage, 0, 0, destWidth, destHeight );
return (Image) bitmap;
}
}
Ha a bemenetünk stream, akkor abból az Image.FromStream metódussal lehet Image objektumot készíteni. Ha byte[], akkor még egy MemorySteam is kell és persze minden IDisposable:
using( MemoryStream originalStream = new MemoryStream( originalContent ) )
{
using( Image originalImage = Image.FromStream( originalStream ) )
{
using( Image resizedImage = ResizeImage( originalImage, MaxWidth, MaxHeight ) )
{
using( MemoryStream resizedStream = new MemoryStream() )
{
resizedImage.Save( resizedStream, ImageFormat.Jpeg );
byte[] resizedContent = resizedStream.ToArray();
}
}
}
}
Tapasztalatom szerint a 100 pixel környékére kicsinyített fényképeknél a JPEG és a PNG hasonló minőséget produkál, miközben a JPEG fájl lényegesen kisebb, nem ritkán tízszeres különbség is van.