Всякий раз, когда вы изменяете размеры изображений, вы будете иметь некоторую потерю качества - нет пути к этому, но вы можете помочь минимизировать это, используя самые высокие параметры качества для графического контекста.
Вот что я использую, используя простые функции GDI +:
public static Bitmap ResizeImage(Bitmap bmp, int width, int height,
InterpolationMode mode = InterpolationMode.HighQualityBicubic)
{
Bitmap bmpOut = null;
try
{
decimal ratio;
int newWidth = 0;
int newHeight = 0;
// If the image is smaller than a thumbnail just return original size
if (bmp.Width < width && bmp.Height < height)
{
newWidth = bmp.Width;
newHeight = bmp.Height;
}
else
{
if (bmp.Width == bmp.Height)
{
if (height > width)
{
newHeight = height;
newWidth = height;
}
else
{
newHeight = width;
newWidth = width;
}
}
else if (bmp.Width >= bmp.Height)
{
ratio = (decimal) width/bmp.Width;
newWidth = width;
decimal lnTemp = bmp.Height*ratio;
newHeight = (int) lnTemp;
}
else
{
ratio = (decimal) height/bmp.Height;
newHeight = height;
decimal lnTemp = bmp.Width*ratio;
newWidth = (int) lnTemp;
}
}
//bmpOut = new Bitmap(bmp, new Size( newWidth, newHeight));
bmpOut = new Bitmap(newWidth, newHeight);
bmpOut.SetResolution(bmp.HorizontalResolution, bmp.VerticalResolution);
Graphics g = Graphics.FromImage(bmpOut);
g.InterpolationMode = mode;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.FillRectangle(Brushes.White, 0, 0, newWidth, newHeight);
g.DrawImage(bmp, 0, 0, newWidth, newHeight);
}
catch
{
return null;
}
return bmpOut;
}
При этом размер изображения увеличивается до наибольшего из ширины или высоты - вы можете изменить этот алгоритм в соответствии с вашими требованиями к изменению размера.
Если вы хотите работать с файлами, вы можете добавить еще один помощник, заключающий в себе код выше:
public static bool ResizeImage(string filename, string outputFilename,
int width, int height,
InterpolationMode mode = InterpolationMode.HighQualityBicubic)
{
using (var bmpOut = ResizeImage(filename, width, height, mode) )
{
var imageFormat = GetImageFormatFromFilename(filename);
if (imageFormat == ImageFormat.Emf)
imageFormat = bmpOut.RawFormat;
bmpOut.Save(outputFilename, imageFormat);
}
return true;
}
GDI + в целом - не лучшее решение для высококачественной обработки изображений - оно вполне приемлемо, но если вам нужно высочайшее качество, лучшую производительность и безопасность потоков в веб-приложениях, вам нужно рассмотреть другие варианты.
Бертран Лерой недавно написал отличную статью об изменении размера изображения, в которой предлагаются некоторые альтернативы с использованием базовых .NET-фреймворков. http://weblogs.asp.net/bleroy/state-of-net-image-resizing-how-does-imageresizer-do