#c# #image-processing #gdi
#c# #обработка изображений #gdi
Вопрос:
Итак, мне нужно немного изменить размер.
Я нашел два разных метода.
Один из них выглядит следующим образом:
public static Byte[] ResizeImageNew(System.Drawing.Image imageFile, int targetWidth, int targetHeight) {
using(imageFile){
Size newSize = CalculateDimensions(imageFile.Size, targetWidth, targetHeight);
using (Bitmap newImage = new Bitmap(newSize.Width, newSize.Height, PixelFormat.Format32bppRgb)) {
newImage.SetResolution(imageFile.HorizontalResolution, imageFile.VerticalResolution);
using (Graphics canvas = Graphics.FromImage(newImage)) {
canvas.SmoothingMode = SmoothingMode.AntiAlias;
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
canvas.PixelOffsetMode = PixelOffsetMode.HighQuality;
canvas.DrawImage(imageFile, new Rectangle(new Point(0, 0), newSize));
MemoryStream m = new MemoryStream();
newImage.Save(m, ImageFormat.Jpeg);
return m.GetBuffer();
}
}
}
}
И другой:
public static System.Drawing.Image ResizeImage(System.Drawing.Image originalImage, int width, int maxHeight) {
originalImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
originalImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
int NewHeight = originalImage.Height * width / originalImage.Width;
if (NewHeight > maxHeight) {
// Resize with height instead
width = originalImage.Width * maxHeight / originalImage.Height;
NewHeight = maxHeight;
}
System.Drawing.Image newImage = originalImage.GetThumbnailImage(width, NewHeight, null, IntPtr.Zero);
return newImage;
}
Я в основном «позаимствовал» оба метода и просто изменил отдельные фрагменты.
Однако, используя первый, всякий раз, когда я изменяю размер изображения на немного меньший, размер файла на самом деле больше исходного (!?)
И второе, хотя и значительно улучшающее размер, выглядит ужасно :/
Я, конечно, склоняюсь к простому улучшению качества изображения первым методом, если это возможно, но я не вижу, как, с моей точки зрения, все выглядит «высококачественным»?
Ответ №1:
Возможно, вам придется установить уровень сжатия JPEG. В настоящее время это, вероятно, сохраняет на очень высоком уровне качества, что может быть не тем, что вы желаете.
Смотрите здесь для получения дополнительной информации: http://msdn.microsoft.com/en-us/library/bb882583.aspx
Обратите внимание, однако, что простое уменьшение разрешения изображения не обязательно уменьшает размер файла. Из-за того, как работает сжатие, файл меньшего разрешения, который был размыт из-за режимов интерполяции, может быть значительно больше оригинала, хотя в JPEG это, вероятно, не вызывает большой озабоченности из-за алгоритма с потерями. Однако для PNG это может иметь огромное значение, если исходный файл раньше был очень простым (например, «плоский» веб-комикс или простая векторная графика) и был размыт после изменения размера.
Ответ №2:
Независимо от проблем с размером файла, я бы определенно рекомендовал использовать первый метод, а не тот, который использует GetThumbnailImage
.
GetThumbnailImage
фактически извлечет внедренный эскиз из исходного изображения, если таковой существует. К сожалению, это означает, что вы масштабируете файл неизвестного размера и качества (по сравнению с оригиналом), если вы не ожидаете и не принимаете во внимание внедренный эскиз. Это также означает, что вы получите результаты совершенно иного качества при одном запуске (со встроенным эскизом), чем при другом запуске (без встроенного эскиза).
Я много раз использовал нечто похожее на ваш первый метод, и хотя я видел то, что вы видите время от времени, результаты были просто неизменно лучше.