检测JPG压缩率?

6
通常情况下,当一张图片被上传到我的网站时,我会使用一个我编写的图像库将其保存为80%默认质量的jpg格式。当需要对它进行其他操作(如裁剪或缩放)时,图像将以jpg格式打开,处理后再保存。然而,如果它之前已经被压缩过了,我就不想再次压缩它,否则每次进行操作时质量都会下降。
有没有办法通过标准GD php库中的工具检测出图片已经被压缩了多少(相对于它的png版本),以便避免重复压缩?我知道一些检测图像是否经过Photoshop处理的工具是通过比较相对压缩量来实现的,因此我认为检测压缩量是可能的,但有没有人知道如何进行这种计算呢?谢谢。

据我所知,您无法从JPG文件中获取质量率。 - Eric Yin
1
我知道它不保存在文件本身的元数据中,但也许有一些方法可以计算它。 - hackartist
2
如果您有足够的空间,您可能希望保留原始文件(但不公开)。然后,当您需要进行更多处理时,您可以在原始文件上进行处理,这样您就不必担心持续重新压缩会破坏图像质量。 - John Flatness
@Flatness:谢谢你的建议,事实上我最初就是这么做的,但问题是随着时间的推移,我会进行各种操作(调整大小、裁剪、颜色转换等),我必须保留一个中间版本,或者将从原始版本到当前版本所需的操作保存在某个地方,这并不值得。 - hackartist
4个回答

10

在JPG格式中,你无法获取到图片的质量值。此外,质量值取决于编码器,它不是一个标准或类似的东西。有些程序只有(低、中、高)三个选项,有些情况下20的质量可能比90好。

其次,每次重新编码后,即使你每次都以最佳质量保存,JPG格式仍然会失去一部分质量。这就是生活的悲哀 :) 只有翻转和旋转(如果对齐了JPEG块大小,还包括裁剪)是不会降低质量的操作。

重要提示:每次使用相同的质量值进行编码。例如:如果你第一次将其保存为60,那么下一次保存为80就没有任何意义,只会让文件变得更大。

另外,尽量减少这种重新编码的次数,并在原始文件上执行每个操作,如果有足够的存储空间。


1
为了避免多次压缩图像,您可以将调整大小后的文件大小与原始文件进行比较。
- 如果文件大小明显变大,则增加了比率,因此不要使用它。 - 如果文件大小明显较小,则已经压缩,所以可以使用它。
此外,由于使用相同比率重新压缩文件只会减少一小部分文件大小,因此如果您使用圆整数来表示比率(60%、70%、80%等),则可以确定比率,如果调整大小后的文件大小与原始文件非常相似。
例如,在以下情况下压缩一个1,844 KB的文件: - 90%= 2,115 KB。文件大小增加,因此我不会使用它。 - 80%= 1,843 KB。这几乎与原始文件大小相同,因此我可以假设原始文件具有80%的比率。 - 70%= 1,567 KB。已经压缩,因此我将使用它。
最后,如果您只关心自己压缩的图像的比率,则可以使用PHP将您使用的比率保存在文件元数据中。

1

您需要将图像的质量存储在数据库中,以便您知道它是否已经被压缩。


即使他调整图像的大小,质量也会下降。保存这样的图像是毫无意义的。 但是,好想法,所以加一分。 - Rok Kralj
@RokKralj 我建议保存,这样他就不会压缩多次。他可能会使图像变得更糟。 - ppp
你可能不是完全理解了。这里没有所谓的“压缩”,只是按质量值保存。如果你的意思是他第一次以80的质量值进行保存,那么记住,下一次他可以保存在100的质量值上……但那只会增加文件大小而无任何质量提高。80 -> 80 -> 80 才是正确的保存方式。 - Rok Kralj
不,我的意思是他可以存储80的值,并执行类似于if($stored_quality > 80){ //执行操作并压缩} else {//仅执行操作}的操作。这样,唯一的质量损失将来自操作,而他不会每次都降低图像的质量。当然,增加质量不是一个选项。 - ppp

0

如果一个JPG图像只被编码一次,你实际上可以以一定的确定度检测它被压缩的质量。

你可以使用一个命令行工具叫做identify来完成这个任务,它是Imagemagick的一部分(也可以作为PHP库使用,见下文)。例如,你可以运行以下命令:

identify -verbose 11397254.jpg

然后你会得到如下输出:

Image: 11397254.jpg
  Format: JPEG (Joint Photographic Experts Group JFIF format)
  Mime type: image/jpeg
  Class: DirectClass
  Geometry: 600x833+0+0
  Units: Undefined
  Type: TrueColor
  Endianess: Undefined
  Colorspace: sRGB
  Depth: 8-bit
  Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit
  Channel statistics:
    Pixels: 499800
    Red:
      min: 7 (0.027451)
      max: 251 (0.984314)
      mean: 205.535 (0.80602)
      standard deviation: 40.8098 (0.160038)
      kurtosis: 7.3041
      skewness: -2.81763
      entropy: 0.627683
    Green:
      min: 4 (0.0156863)
      max: 237 (0.929412)
      mean: 200.186 (0.785044)
      standard deviation: 45.9241 (0.180095)
      kurtosis: 3.86968
      skewness: -2.25667
      entropy: 0.6339
    Blue:
      min: 0 (0)
      max: 241 (0.945098)
      mean: 191.701 (0.75177)
      standard deviation: 54.6716 (0.214399)
      kurtosis: 1.22795
      skewness: -1.70134
      entropy: 0.664107
  Image statistics:
    Overall:
      min: 0 (0)
      max: 251 (0.984314)
      mean: 199.141 (0.780945)
      standard deviation: 47.4814 (0.186202)
      kurtosis: 3.61004
      skewness: -2.23079
      entropy: 0.641896
  Rendering intent: Perceptual
  Gamma: 0.454545
  Chromaticity:
    red primary: (0.64,0.33)
    green primary: (0.3,0.6)
    blue primary: (0.15,0.06)
    white point: (0.3127,0.329)
  Background color: white
  Border color: srgb(223,223,223)
  Matte color: grey74
  Transparent color: black
  Interlace: JPEG
  Intensity: Undefined
  Compose: Over
  Page geometry: 600x833+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: JPEG
  Quality: 100
  Orientation: Undefined
  Properties:
    date:create: 2020-10-28T09:13:49+01:00
    date:modify: 2020-10-28T09:13:45+01:00
    jpeg:colorspace: 2
    jpeg:sampling-factor: 2x2,1x1,1x1
    signature: 7b5dc010915e4ae8b89891f7259a6f22efc69a31e5244403db580b70adc2ee94
  Artifacts:
    filename: 11397254.jpg
    verbose: true
  Tainted: False
  Filesize: 147KB
  Number pixels: 500K
  Pixels per second: 49.98MB
  User time: 0.010u
  Elapsed time: 0:01.010
  Version: ImageMagick 6.9.7-4 Q16 x86_64 20170114 http://www.imagemagick.org

重要的代码行在哪里:
  Compression: JPEG
  Quality: 100

如果质量为100,那么这张图片就没有被压缩过。
我用这个工具测试了GIMP的JPG压缩,它非常准确地检测了我在图像上使用的压缩百分比。
在PHP中,ImageMagick库中有一个函数:

https://www.php.net/manual/en/imagick.identifyimage.php

它似乎是同一工具的移植,你可以查看一下。


JPG质量100仍然不意味着无损压缩。(当然,这并不意味着图像没有被压缩;它仍然比相应的PNG文件小得多,更不用说BMP了。)除此之外: 是的,可以检测图像质量(identify实用工具或像IrfanView这样的图像编辑器可以显示它); 但是如何以编程方式实现这一点仍然不清楚。 - Mike Rosoft
因此:ImageMagic的identify实用程序(或其他显示图像质量的软件)只是通过分析图像本身来估计质量。似乎没有关于JPG图像质量的客观定义。请参见https://superuser.com/questions/62730。(可以从该问题中的图像中看出这一点,对于这些图像,IrfanView报告的质量与ImageMagic不同,但大致相当。如果图像的质量约为100%,但存在严重的伪影,这也可能意味着已经在100%处重新编码了图像,包括JPG伪影。) - Mike Rosoft

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接