【问题标题】:Detect JPEG image quality检测JPEG图像质量
【发布时间】:2013-07-18 06:40:15
【问题描述】:

我允许用户上传图片。但是,我想保持 JPEG 质量不超过 90%。我打算做的是检测当前的质量: - 如果少于 90% 什么都不做 - 如果超过 90%,则使用 Image Magick 将图像重新压缩到 90%

可以这样做吗?我更喜欢 PHP,但任何语言都会有所帮助。

【问题讨论】:

标签: php imagemagick jpeg


【解决方案1】:

您不能保证质量设置存储在 JPEG 的元数据中。这是编码器设置,而不是图像属性。

在这里阅读更多关于estimating JPEG quality的信息

简单地定义最大文件大小可能更有意义。归根结底,限制图像质量就是为了节省带宽。所以设置图片尺寸和文件大小的比例比较合适。

【讨论】:

  • 感谢您的回答。我犹豫着决定接受它。我选择了约瑟夫的那个,因为它在他的长回答中得到了很好的解释。谢谢。
【解决方案2】:

paddy 是正确的,此设置并不总是存储在 JPEG 文件中。如果是,那么您可以使用 Imagemagick 的identify 来读取质量。例如:

$ identify -format '%Q' tornado_ok.jpg

93%

更新:基于对这个问题的回答 https://superuser.com/questions/62730/how-to-find-the-jpg-quality我 发现显然identify 命令仍然可以确定 通过对量化表进行逆向工程来提高质量,即使所有 图像 EXIF / 其他元数据丢失。顺便说一句,标题 您现在的问题可能与该问题重复 我链接到的问题。

但对我来说,你的问题本身就有价值,因为在你的 问题的文字你解释你正在尝试做什么,这是更多 而不是简单地检测 jpeg 质量。不过,你或许应该 如果您想反映您正在尝试解决问题,请更新标题 比仅仅读取 JPEG 图像质量更具体的问题。

除非您要存档原始图像,否则对于网络使用来说,即使 90% 也是过度的。过去 75% 是默认值(只有在仔细检查并排图像之间才能看到降级),现在在高带宽时代,85% 是一个非常高质量的选项。 90% 和 85% 之间 5% 的质量差异几乎是不可见的,但通常会为您节省 30% 以上的文件大小。 JPEG 算法的设计初衷是在压缩的第一阶段(超过 80% 左右)消除人类感知不可见的信息。

更新/注意:我所说的压缩质量设置是 来自使用非常广泛的 JPEG 库 libjpeg 的测试。 Photoshop的 压缩百分比和其他软件的质量设置都是 独立的,不一定与设置的意思相同 libjpeg 的。

paddy 使用图像高度和图像宽度来计算可接受的文件大小的想法是合理的:

您可以像这样获取图像的高度/宽度:

list($originalWidth, $originalHeight) = getimagesize($imageFile);

我自己的高品质照片发布在网上,比如这张:http://ksathletics.com/2013/wsumbb/nw.jpg 通常以每百万像素大约 200 KB 的比率保存。

因此,例如,您可以将宽度乘以高度并除以 1000000 来计算图像中的百万像素。将文件大小除以 1024 以计算 KB。然后将得到的 KB 除以百万像素。如果结果低于 200 或您决定的任何值,那么您不需要重新压缩它。否则,您可以以 85% 的质量或您决定的任何质量重新压缩它。

【讨论】:

  • 事实上,我目前的质量设置是 85%,但一些贡献者甚至说它很难看。因为我不存档原始图像,所以我需要相当高的质量(对于衍生图像,如缩略图,我使用较低的质量)。使用尺寸/尺寸比率作为阈值听起来很合理。我选择你的答案是因为它解释得很好。谢谢。
【解决方案3】:

怎么了?我正在开发的应用程序遇到同样的问题......我的问题是,我从一个随机站点中提取了几张图片,每个项目都有几张图片,我想为每个项目显示一个图片,并带来为用户提供最优质的图像。

我提出了这个想法,它非常简单,适用于任何语言和任何类型的压缩:

//Parameters you will need to retrieve from image
$width = 0; 
$height = 0;
$filesize = 0;

//Quality answer for your image
$quality = (101-(($width*$height)*3)/$filesize);

我针对上面提到的http://fotoforensics.com/tutorial-estq.php 运行了这个算法,结果如下:

Filename            Width   Height  Pixels  BitmapBytes FileBytes   Quality 
estq-baseline.png   400     300     120000  360000      163250      98,79
estq-90.jpg         400     300     120000  360000      34839       90,67
estq-80.jpg         400     300     120000  360000      24460       86,28
estq-70.jpg         400     300     120000  360000      19882       82,89
estq-25.jpg         400     300     120000  360000      10300       66,05

该算法背后的基本思想是将图像以位图方式(不进行任何压缩,每像素 3 个字节,RGB 为 3 个字节)写入时可以达到的大小与该图像当前使用的大小进行比较。图像尺寸越小,压缩率越高,与所使用的压缩方法无关,而是使用 JPG、PNG 或其他格式,这将导致我们在未压缩和压缩图像之间存在更大或更小的间隙。

还需要提一下,这是一个用于比较目的的数学解决方案,此方法不会返回图像的实际质量,它会回答未压缩和压缩尺寸之间的距离百分比!

如果您需要更多详细信息,可以给我发送电子邮件:rafaelkarst@gmail.com

【讨论】:

  • 太棒了。谢谢。
【解决方案4】:

由于 OP 表示他更喜欢 php,我提供以下内容:

$img = new Imagick($filename);
$quality = $img->getImageCompressionQuality();

【讨论】:

    【解决方案5】:

    对于那些使用 GraphicsMagick 而不是 ImageMagick 的人,您可以使用以下命令获取 JPEG 质量:

    gm identify -format '%[JPEG-Quality]' path_to/image_file.jpg
    

    并根据文档 http://www.graphicsmagick.org/GraphicsMagick.html#details-format

    请注意,JPEG 没有“质量”的概念,软件使用和估计的质量度量是基于 IJG JPEG 6b 建立的质量度量。其他编码器(例如 Adob​​e Photoshop 使用的编码器)使用不同的编码指标。

    【讨论】:

    • 正确的格式选项不是“%[JPEG-Quality]”,而是“%Q”。所以应该是:gm identify -format '%Q' path_to/image_file.jpg
    【解决方案6】:

    如果您的 jpeg 是使用标准图像量化表的直接缩放创建的并且根据独立 JPEG 组的公式使用 0-100 质量,那么,假设您有亮度量化表在一个名为quantization的数组中(如image.quantization[0]中提供的Python的PIL模块),则可以通过以下方式获得原始值:

    if quantization[58] <= 100:
        originalQuality = int(100 - quantization[58] / 2)
    else:
        originalQuality = int(5000.0 / 2.5 / quantization[15])
    

    基本上,默认亮度量化值#15 是 40,#58 是 100,因此这些值可以方便地从中提取结果。 IJG 通过5000 / Q 将值缩放到大约 50,通过200 - 2 * Q 缩放到低于 50。如果质量设置小于 8,这将不会给出不错的结果(如果 quantization[5] == 255)——在这种情况下,也许使用量化表位置 #5

    https://www.rfc-editor.org/rfc/rfc2435#section-4.2

    【讨论】:

      【解决方案7】:

      这是一个 PHP 函数,它尝试了所有可用的获取质量的方法(据我所知):

      /* Try to detect quality of jpeg.
         If not possible, nothing is returned (null). Otherwise quality is returned (int)
          */
      function detectQualityOfJpg($filename)
      {
          // Try Imagick extension
          if (extension_loaded('imagick') && class_exists('Imagick')) {
              $img = new Imagick($filename);
      
              // The required function is available as from PECL imagick v2.2.2
              if (method_exists($img, 'getImageCompressionQuality')) {
                  return $img->getImageCompressionQuality();
              }
          }
      
          if (function_exists('shell_exec')) {
      
          // Try Imagick
              $quality = shell_exec("identify -format '%Q' " . $filename);
              if ($quality) {
                  return intval($quality);
              }
      
              // Try GraphicsMagick
              $quality = shell_exec("gm identify -format '%Q' " . $filename);
              if ($quality) {
                  return intval($quality);
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-08
        • 2021-07-03
        相关资源
        最近更新 更多