检测JPEG图像质量

时间:2013-07-19 04:47:58

标签: php imagemagick jpeg

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

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

7 个答案:

答案 0 :(得分:6)

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图像质量更具体的问题。

除非您要归档原始图像,否则对于Web使用,即使90%也是过量的。 75%曾经是过去的默认设置(只有在并排图像之间仔细检查才能看到降级),现在在高带宽的时代,85%是一个非常高质量的选择。 90%和85%之间的5%质量差异实际上是不可见的,但通常会节省超过30%的文件大小。 JPEG算法旨在首先消除人类感知在其第一个压缩阶段(超过80%左右)不可见的信息。

  

更新/注意:我正在谈论的压缩质量设置是   来自libjpeg的测试,这是一个非常广泛使用的JPEG库。 Photoshop的   压缩百分比和其他软件的质量设置都是   独立,并不一定意味着与设置相同的东西   libjpeg。

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

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

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

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

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

答案 1 :(得分:5)

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

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

//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等等,这将导致我们在未压缩和压缩图像之间产生更大的间隙或更小的间隙。 / p>

同样重要的是,这是一个用于比较目的的数学解决方案,此方法不会返回图像的实际质量,它将回答未压缩和压缩大小之间的距离百分比!

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

答案 2 :(得分:5)

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

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

答案 3 :(得分:1)

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

在此处详细了解estimating JPEG quality

简单地定义最大文件大小可能更有意义。在一天结束时,限制图像质量就是节省带宽。因此,设置图像尺寸和文件大小之间的比例更合适。

答案 4 :(得分:0)

对于那些使用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建立的质量度量。其他编码器(例如Adobe Photoshop使用的编码器)使用不同的编码指标。

答案 5 :(得分:0)

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

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://tools.ietf.org/html/rfc2435#section-4.2

答案 6 :(得分:0)

这是一个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);
        }
    }
}