【问题标题】:How to measure quality of image before compressing如何在压缩前测量图像质量
【发布时间】:2014-04-02 18:27:16
【问题描述】:

我正在使用 C#。

我有一张 jpeg 图片。

我通过降低图像质量来压缩它,所以:

byte[] data = SaveJpeg(myJPEG, 60);

public byte[] SaveJpeg(Image img, int quality)
{
    byte[] data = null;
    // Encoder parameter for image quality 
    EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
    // Jpeg image codec 
    ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");
    EncoderParameters encoderParams = new EncoderParameters(1);
    encoderParams.Param[0] = qualityParam;
    using (MemoryStream ms = new MemoryStream())
    {
        img.Save(ms, jpegCodec, encoderParams);
        data = ms.ToArray();
        img.Dispose();
    }
    return data;
  }

  private ImageCodecInfo GetEncoderInfo(string mimeType)
  {
      // Get image codecs for all image formats 
      ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

      // Find the correct image codec 
      for (int i = 0; i < codecs.Length; i++)
         if (codecs[i].MimeType == mimeType)
             return codecs[i];
      return null;
    }

我的图片按预期缩小了。

这个特殊的图像“看起来”质量很高,压缩后返回 20818(以字节为单位)。但是对于具有相同分辨率(即宽度 + 高度)但“看起来”较差的图像的其他图像,返回的字节大小要小得多 - 例如 9000 字节。

我能否获得一个一致的进程,该进程将返回“大致”相同数量的字节?图片中影响压缩大小的因素有哪些?

【问题讨论】:

    标签: c# image-processing


    【解决方案1】:

    首先,“质量”在 JPEG 中是一个毫无意义的术语。各种编码器使用质量值作为指定压缩中使用的量化表的简化方法。

    量化表的效果取决于图像本身。没有办法有一个特定的设置来提供大小相同的文件并以 JPEG 格式输出。

    二、影响图像外压缩的因素有:

    1. 图像本身的性质。
    2. 使用的采样。通常使用比 Y 分量更少的 Cr 和 Cr 分量样本。如果你为一个有 4 个 Y 值的矩形取 1 个 Cb 和 1 个 Cr 值,你已经将数据量减少了一半。
    3. 使用的量化表。

    第三,如果你进入图像内部,这意味着图像被划分为 8x8 块,产生接近零的高阶 DCT 值,压缩效果更好。我知道除非您了解 JPEG 的内部结构,否则这是毫无意义的。

    一些可见的因素:

    大的实心区域可以很好地压缩。一个全部为一种颜色的 8x8 块会产生一组 8x8 的 DCT 值,除了一个之外,这些值都为零。此外,在这些区域对 Cb 和 Cb 进行二次采样对输出没有负面影响。

    干净的过渡在产生良好的输出时不会很好地压缩。

    像素级颜色的剧烈来回变化不能很好地压缩。

    【讨论】:

    • 所有非常有趣的东西!我将考虑应用“每 4 年取 1 Cb 和 1 Cr 值”。最好的方法是对这 4 个 Cr 和 4 个 Cb 使用平均过滤器吗?
    • 这是正常的方式。您应该检查您的文件格式标准以确定支持哪些子采样。 JPEG 标准允许任何东西(例如 3:2 采样),但实现的文件格式不允许。
    • 你好。我将图像加载到 emgu 中。我使用 ycc 的色彩空间。我使用 emgu 图像类公开的数据数组来枚举图像。我将 Cb + Cr 的值“拉平/平均”。生成的图像看起来相同,但颜色的一些多样性减少了(这是预期的)。字节大小与原始大小相同。我尝试过使用 x4、x8 和 x16 进行采样。字节数组大小始终相同。我这样做是正确的还是..?感谢您可能拥有的任何其他 cmets :) 谢谢
    • 您是自己采样还是使用库?你的图书馆支持吗?这里的第 4 页讨论了 JFIF 中的采样。这一点更清楚,因为平均应该考虑到周围的像素以及减少块效应。
    • 嗨,您的评论中没有链接供我阅读:(。是的,我自己在进行采样。当我在采样后检查像素值时,然后通过 2x2 像素块,cb和 cr 已被平均化,而 y 分量保持不变。处理后我几乎可以辨别图像颜色的差异。感谢您抽出时间回复我..
    【解决方案2】:

    除了原始图像的分辨率和文件大小之外,还涉及更多内容。图像中的内容会影响可以压缩的程度;所以你不能真正做到这一点。

    但还有更多,甚至。先前/现有的压缩实际上是无关紧要的。 JPEG 是一种“有损”格式……因此不涉及解压缩。奇怪的是:以最高质量(最低压缩)保存图像,您通常会得到比原来更大的文件大小。通常,更大。

    【讨论】:

    • 您好,感谢您的评论和观察。我曾怀疑是图像中的哪些排列影响了压缩。我唯一的目标是将图像上传到我的网络服务器,以字节为单位尽可能小,而不会损失太多质量。我似乎无法找到一种方法来做到这一点......
    猜你喜欢
    • 2011-04-12
    • 1970-01-01
    • 2011-08-05
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多