Помощь с методами изменения размера изображений gdi

#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 фактически извлечет внедренный эскиз из исходного изображения, если таковой существует. К сожалению, это означает, что вы масштабируете файл неизвестного размера и качества (по сравнению с оригиналом), если вы не ожидаете и не принимаете во внимание внедренный эскиз. Это также означает, что вы получите результаты совершенно иного качества при одном запуске (со встроенным эскизом), чем при другом запуске (без встроенного эскиза).

Я много раз использовал нечто похожее на ваш первый метод, и хотя я видел то, что вы видите время от времени, результаты были просто неизменно лучше.