Веб-сайт, над которым я работаю, создает свои эскизы, используя API-интерфейсы WPF вместо GDI +.Вам нужно добавить две ссылки на ваш проект, чтобы включить это: WindowsBase, PresentationFramework и PresentationCore.Вот базовый пример того, как код может быть использован:
try
{
using (var input = File.Open(inputFilename, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var thumb = File.Open(thumbFilename, FileMode.Create, FileAccess.Write, FileShare.None))
{
Thumbnail(input, thumb, 200, 100);
}
}
catch (MyException)
{
File.Delete(thumbFilename);
}
Это помещает миниатюру в прямоугольник 200x100, сохраняя соотношение сторон.
(Реальный сайт не делает этогосовсем как выше. Что мы на самом деле делаем, это пытаемся сгенерировать наименьший миниатюра в обработчике POST загрузки файла. Мы используем поток памяти для хранения полученного миниатюры. Если миниатюра может быть сгенерирована правильно, мы сохраняем загрузку и маленький миниатюрув противном случае мы возвращаем клиенту сообщение об ошибке. Другие размеры эскизов создаются на лету и кэшируются.)
Вот код - обратите внимание, что я, возможно, немного испортил при преобразовании этого во что-то повторно используемое, новсе основные биты должны быть там.Обратите внимание, что он сохраняет все эскизы в формате JPEG, но допускает несколько форматов ввода, включая JPEG и PNG.Это может или не может быть хорошо для вас.
private static void Thumbnail(Stream source, Stream destination, int maxWidth, int maxHeight)
{
int width = 0, height = 0;
BitmapFrame frame = null;
try
{
frame = BitmapDecoder.Create(source, BitmapCreateOptions.None, BitmapCacheOption.None).Frames[0];
width = frame.PixelWidth;
height = frame.PixelHeight;
}
catch
{
throw new MyException("The image file is not in any of the supported image formats.");
}
if (width > AbsoluteLargestUploadWidth || height > AbsoluteLargestUploadHeight)
throw new MyException("This image is too large");
try
{
int targetWidth, targetHeight;
ResizeWithAspect(width, height, maxWidth, maxHeight, out targetWidth, out targetHeight);
BitmapFrame targetFrame;
if (frame.PixelWidth == targetWidth && frame.PixelHeight == targetHeight)
targetFrame = frame;
else
{
var group = new DrawingGroup();
RenderOptions.SetBitmapScalingMode(group, BitmapScalingMode.HighQuality);
group.Children.Add(new ImageDrawing(frame, new Rect(0, 0, targetWidth, targetHeight)));
var targetVisual = new DrawingVisual();
var targetContext = targetVisual.RenderOpen();
targetContext.DrawDrawing(group);
var target = new RenderTargetBitmap(targetWidth, targetHeight, 96, 96, PixelFormats.Default);
targetContext.Close();
target.Render(targetVisual);
targetFrame = BitmapFrame.Create(target);
}
var enc = new JpegBitmapEncoder();
enc.Frames.Add(targetFrame);
enc.QualityLevel = 80;
enc.Save(destination);
}
catch
{
throw new MyException("The image file appears to be corrupt.");
}
}
/// <summary>Generic helper to compute width/height that fit into specified maxima while preserving aspect ratio.</summary>
public static void ResizeWithAspect(int origWidth, int origHeight, int maxWidth, int maxHeight, out int sizedWidth, out int sizedHeight)
{
if (origWidth < maxWidth && origHeight < maxHeight)
{
sizedWidth = origWidth;
sizedHeight = origHeight;
return;
}
sizedWidth = maxWidth;
sizedHeight = (int) ((double) origHeight / origWidth * sizedWidth + 0.5);
if (sizedHeight > maxHeight)
{
sizedHeight = maxHeight;
sizedWidth = (int) ((double) origWidth / origHeight * sizedHeight + 0.5);
}
}