简体   繁体   English

调整jpeg图像的大小会影响其压缩吗?

[英]Does resizing jpeg images affect their compression?

I'm resizing jpegs by using the Graphics.DrawImage method (see code fragment below). 我正在使用Graphics.DrawImage方法调整jpeg的大小(请参见下面的代码片段)。 Can anyone confirm that this will not affect the compression of the new image? 谁能确认这不会影响新图像的压缩? I have seen this thread , but I am talking specifically about compression of jpegs. 我已经看到了这个线程 ,但是我专门谈论的是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();

    }

JPEGs have no "compression" value saved within them. JPEG中没有保存“压缩”值。 When you resize and save them, they are compressed with whatever value you tell your save function to use. 调整大小并保存它们时,它们会使用您告诉保存函数使用的任何值进行压缩。 As you are not passing a value, it will just use whatever default for the library is. 由于您没有传递值,它将只使用库的默认值。

Resizing an image effects the compression, if by "compression" you refer to how much detail can be fitted into how many pixels. 调整图像大小会影响压缩,如果通过“压缩”来指代可以在多少像素中容纳多少细节。

The JPEG compression algorithm favors blurry or homogeneous images with gradients and flat patches of colors. JPEG压缩算法支持具有梯度和平坦色块的模糊或均匀图像。 Therefore there isn't a direct correlation between image dimensions and the resultant file size. 因此,图像尺寸与生成的文件大小之间没有直接关联。 What matters most is the amount of detail in the image (all images were saved as JPEG with 80% loss factor): 最重要的是图像中的细节量(所有图像均以80%的损耗因子保存为JPEG):

  1. The original SO logo: 原始的SO徽标:

    Original http://magnetiq.com/exports/sologo/original.jpg 原始http://magnetiq.com/exports/sologo/original.jpg

    File size: 4,483 bytes

  2. Preserve the dimensions and apply a heavy Gaussian blur: 保留尺寸并应用高斯模糊:

    Blurred http://magnetiq.com/exports/sologo/blurred.jpg 模糊的http://magnetiq.com/exports/sologo/blurred.jpg

    File size: 1,578 bytes

  3. Resize the original to 1/4: 将原始尺寸调整为1/4:

    Shrunk http://magnetiq.com/exports/sologo/shrunk.jpg 缩小http://magnetiq.com/exports/sologo/shrunk.jpg

    File size: 2,063 bytes

Note that the blurred image (2), even though it's 4 times as large as the shrunk one (3) is tinier in file size than both (1) and (2). 请注意,模糊的图像(2)即使是缩小的图像(3)的4倍,其文件大小也比(1)和(2)都小。 Blurring adds nice gradients that make JPEG compression happy. 模糊添加了不错的渐变,使JPEG压缩令人满意。

The small image (3), although it only has 1/4 the pixels that the original has (1), isn't quite 1/4 the file size. 小图像(3)尽管仅具有原始图像(1)的1/4像素,但并不是文件大小的1/4。 This is because shrinking the image results in finer details and JPEG compression doesn't like that. 这是因为缩小图像会产生更好的细节,而JPEG压缩则不是如此。

When you call "bmpOut.Save" you have to pass in some EncoderParameters to tell the method what quality level you would like to save it with. 当您调用“ bmpOut.Save”时,您必须传递一些EncoderParameters来告诉该方法您希望使用哪种质量级别进行保存。

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

In your code " HighQualityBicubic " is the compression you are using. 在您的代码中,“ HighQualityBicubic ”是您正在使用的压缩方式。 Resizing to a smaller size does remove detail, but that has nothing to do with compression, it just has to do with fewer pixels. 调整为较小的尺寸确实会删除细节,但这与压缩无关,它只与较少的像素有关。

JPEG compression is lossy -- not all of the original data is actually stored exactly. JPEG压缩是有损的 -并非所有原始数据都实际存储准确。 If you compress an image as a JPEG and decompress it, you won't get back the exact original image. 如果将图像压缩为JPEG并解压缩,则不会获得确切的原始图像。 Every time you compress and decompress, you lose a bit of quality. 每次压缩和解压缩都会损失一点质量。

For some simple transformations, such as rotating a JPEG, you can do it losslessly with programs such as jpegtran . 对于一些简单的转换,例如旋转JPEG,您可以使用jpegtran等程序无损地进行转换

However, for resizing images, you can't do it losslessly. 但是,要调整图像大小,就不能无损地做到这一点。 You're definitely going to degrade the quality somewhat when you do this, although probably not by very much. 当您这样做时,您肯定会降低质量,尽管可能不会很大。 If possible, try to use original lossless images as the source for the resize operation to get the highest possible quality, and if you concatenate multiple resize operations, instead just do a single resize from the original. 如果可能,请尝试使用原始的无损图像作为调整大小操作的源,以获取尽可能高的质量,并且如果您将多个调整大小操作串联在一起,则只需对原始大小进行一次调整即可。

Do not confuse the storage format (JPEG) with the format you operate on using the Graphics object. 不要将存储格式(JPEG)与使用Graphics对象进行操作的格式混淆。 The storage format is compressed, the Graphics object works with decompressed data. 存储格式已压缩, Graphics对象使用解压缩的数据。

The LoadImageFromURL method decompresses the information stored in the JPEG, you perform your resize operation on the decompressed data, and when you save it to a JPEG file, it gets compressed again. LoadImageFromURL方法解压缩JPEG中存储的信息,对解压缩后的数据执行调整大小操作,然后将其保存到JPEG文件时,它将再次被压缩。

Since JPEG compression is not lossless, the picture quality will be reduced every time you perform this process: Decompress, mutate, recompress . 由于JPEG压缩并非无损,因此每次执行以下过程都会降低图像质量: 解压缩,变异,重新压缩

If I missunderstood your question: The compression factor you use for saving the image inot set in your code, so it will be at some default value. 如果我误解了您的问题:用于保存代码中图像inot集的压缩因子,那么它将是某个默认值。 If you want to reduce quality loss by saving with a small compression factor, you need to explicitly set it. 如果要通过使用较小的压缩系数进行保存来减少质量损失,则需要对其进行显式设置。

Same as what you already found, but here is the VB.NET version from Circumventing GDI+ default image compression . 与您已经找到的相同,但是这里是Circumventing GDI +默认图像压缩的VB.NET版本。

I personally recommend JPEG quality setting of 90L. 我个人建议JPEG质量设置为90L。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM