1

我正在使用 Graphics.DrawImage 方法调整 jpeg 的大小(请参见下面的代码片段)。谁能确认这不会影响新图像的压缩?我看过这个线程,但我专门谈论 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();

    }
4

7 回答 7

6

JPEG 没有保存在其中的“压缩”值。当您调整大小并保存它们时,它们会使用您告诉保存函数使用的任何值进行压缩。由于您没有传递值,它只会使用库的默认值。

于 2009-02-06T15:29:51.383 回答
4

调整图像大小会影响压缩,如果通过“压缩”您指的是可以将多少细节适合多少像素。

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),即使它是缩小后的图像 (3) 的 4 倍,其文件大小也比 (1) 和 (2) 都小。模糊添加了使 JPEG 压缩满意的漂亮渐变。

小图像 (3) 虽然只有原始图像 (1) 的 1/4 像素,但还不是文件大小的 1/4。这是因为缩小图像会产生更精细的细节,而 JPEG 压缩不喜欢这样。

于 2009-02-06T17:05:22.907 回答
3

当你调用“bmpOut.Save”时,你必须传入一些 EncoderParameters 来告诉方法你想用什么质量级别来保存它。

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

于 2009-02-06T15:35:53.230 回答
1

不要将存储格式 (JPEG) 与您使用Graphics对象操作的格式混淆。存储格式是压缩的,Graphics对象使用解压缩的数据。

LoadImageFromURL方法解压缩存储在 JPEG 中的信息,您对解压缩的数据执行调整大小操作,当您将其保存为 JPEG 文件时,它会再次被压缩。

由于 JPEG 压缩不是无损的,每次执行此过程时图片质量都会降低:解压缩、变异、重新压缩

如果我误解了您的问题:您用于保存代码中设置的图像 int 的压缩因子,因此它将处于某个默认值。如果您想通过使用较小的压缩因子进行保存来减少质量损失,则需要显式设置它。

于 2009-02-06T15:42:05.883 回答
0

在您的代码中“ HighQualityBicubic”是您正在使用的压缩。调整到更小的尺寸确实会删除细节,但这与压缩无关,它只是与更少的像素有关。

于 2009-02-06T15:34:58.583 回答
0

JPEG 压缩是有损的——并不是所有的原始数据都被准确地存储了。如果您将图像压缩为 JPEG 并对其进行解压缩,您将无法取回确切的原始图像。每次压缩和解压缩时,都会损失一点质量。

对于一些简单的转换,例如旋转 JPEG,您可以使用jpegtran等程序无损地进行转换。

但是,对于调整图像大小,您不能无损地进行。当你这样做时,你肯定会在一定程度上降低质量,尽管可能不会降低很多。如果可能,请尝试使用原始无损图像作为调整大小操作的来源以获得尽可能高的质量,如果您连接多个调整大小操作,则只需从原始图像中进行一次调整大小。

于 2009-02-06T15:41:28.867 回答
0

与您已经找到的相同,但这里是来自Circumventing GDI+ default image compression的 VB.NET 版本。

我个人推荐JPEG质量设置为90L。

于 2009-02-06T16:29:12.933 回答