Влияет ли изменение размера изображений JPEG на их сжатие? - PullRequest
1 голос
/ 06 февраля 2009

Я изменяю размеры jpegs с помощью метода Graphics.DrawImage (см. Фрагмент кода ниже). Кто-нибудь может подтвердить, что это не повлияет на сжатие нового изображения? Я видел этот поток , но я говорю конкретно о сжатии JPEG.

    private byte[] getResizedImage(String url, int newWidth)
    {
        Bitmap bmpOut = null;
        System.IO.MemoryStream outStream = new System.IO.MemoryStream();

        //input image is disposable
        using (Bitmap inputImage = LoadImageFromURL(url))
        {
            ImageFormat format = inputImage.RawFormat;
            decimal ratio;  //ratio old width:new width
            int newHeight = 0;

            //*** If the image is smaller than a thumbnail just return it
            if (inputImage.Width < newWidth)
                return null;

            ratio = (decimal)newWidth / inputImage.Width;
            decimal h = inputImage.Height * ratio;
            newHeight = (int)h;

            bmpOut = new Bitmap(newWidth, newHeight);
            Graphics g = Graphics.FromImage(bmpOut);
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            // try testing with following options:
            //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            //g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
            //g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;

            g.FillRectangle(Brushes.White, 0, 0, newWidth, newHeight);
            g.DrawImage(inputImage, 0, 0, newWidth, newHeight);
            bmpOut.Save(outStream, getImageFormat(url));
        }

        return outStream.ToArray();

    }

Ответы [ 7 ]

6 голосов
/ 06 февраля 2009

JPEG не имеет значения "сжатия", сохраненного в них. Когда вы изменяете размер и сохраняете их, они сжимаются с любым значением, которое вы указываете своей функции сохранения. Поскольку вы не передаете значение, оно будет использовать любое значение по умолчанию для библиотеки.

4 голосов
/ 06 февраля 2009

Изменение размера изображения влияет на сжатие, если под «сжатием» вы ссылаетесь на то, сколько деталей можно вписать во сколько пикселей.

Алгоритм сжатия JPEG поддерживает размытые или однородные изображения с градиентами и плоскими пятнами цветов. Поэтому нет прямой связи между размерами изображения и результирующим размером файла. Что наиболее важно, так это количество деталей на изображении (все изображения были сохранены в формате JPEG с коэффициентом потерь 80%):

  1. Оригинальный логотип SO:

    Оригинал http://magnetiq.com/exports/sologo/original.jpg

    File size: 4,483 bytes

  2. Сохраните размеры и примените сильное размытие по Гауссу:

    Размыто http://magnetiq.com/exports/sologo/blurred.jpg

    File size: 1,578 bytes

  3. Изменить размер оригинала до 1/4:

    Сжатый http://magnetiq.com/exports/sologo/shrunk.jpg

    File size: 2,063 bytes

Обратите внимание, что размытое изображение (2), даже если оно в 4 раза больше сокращенного (3), имеет меньший размер файла, чем оба (1) и (2). Размытие добавляет приятные градиенты, которые делают сжатие JPEG счастливым.

Маленькое изображение (3), хотя оно имеет только 1/4 пикселей по сравнению с оригиналом (1), не совсем 1/4 размера файла. Это связано с тем, что сжатие изображения приводит к получению более мелких деталей, а сжатие JPEG не нравится.

3 голосов
/ 06 февраля 2009

Когда вы вызываете "bmpOut.Save", вы должны передать некоторые EncoderParameters, чтобы сообщить методу, с каким уровнем качества вы хотели бы его сохранить.

http://msdn.microsoft.com/en-us/library/system.drawing.imaging.encoderparameters(VS.80).aspx

0 голосов
/ 06 февраля 2009

То же, что вы уже нашли, но вот версия VB.NET от Обход GDI + сжатие изображений по умолчанию .

Я лично рекомендую настройку качества JPEG 90L.

0 голосов
/ 06 февраля 2009

Не путайте формат хранения (JPEG) с форматом, с которым вы работаете, используя объект Graphics. Формат хранения сжат, объект Graphics работает с распакованными данными.

The Метод LoadImageFromURL распаковывает информацию, хранящуюся в JPEG, вы выполняете операцию изменения размера распакованных данных, а когда вы сохраняете ее в файл JPEG, она снова сжимается.

Поскольку сжатие JPEG не без потерь, качество изображения будет ухудшаться при каждом выполнении этого процесса: Распаковка, изменение, повторное сжатие .

Если я неправильно понял ваш вопрос: коэффициент сжатия, который вы используете для сохранения inot изображения, установлен в вашем коде, поэтому он будет иметь некоторое значение по умолчанию. Если вы хотите уменьшить потерю качества за счет сохранения с небольшим коэффициентом сжатия, вам нужно явно установить его.

0 голосов
/ 06 февраля 2009

Сжатие JPEG с потерями - не все исходные данные на самом деле сохраняются точно. Если вы сжимаете изображение в формате JPEG и распаковываете его, вы не получите точного исходного изображения. Каждый раз, когда вы сжимаете и распаковываете, вы теряете немного качества.

Для некоторых простых преобразований, таких как вращение JPEG, вы можете сделать это без потерь с помощью таких программ, как jpegtran .

Однако для изменения размера изображений вы не можете сделать это без потерь. Когда вы это сделаете, вы определенно несколько ухудшите качество, хотя, вероятно, не очень. Если возможно, попробуйте использовать исходные изображения без потерь в качестве источника для операции изменения размера, чтобы получить максимально возможное качество, и если вы объединяете несколько операций изменения размера, вместо этого просто выполните одно изменение размера из исходного.

0 голосов
/ 06 февраля 2009

В вашем коде "HighQualityBicubic" - это сжатие, которое вы используете. Изменение размера до меньшего размера приводит к удалению деталей, но это не имеет ничего общего со сжатием, оно просто связано с меньшим количеством пикселей.

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