有没有可能告诉一个 JPEG 的质量水平?

这实际上是一个由两部分组成的问题,因为我还不完全理解这些东西是如何工作的:

我的情况: 我正在写一个网络应用程序,让用户上传图片。我的应用程序然后调整大小为可显示的东西(例如: 640x480左右) ,并保存文件以供以后使用。

我的问题是:

  1. 给定一个任意的 JPEG 文件,是否有可能告诉质量级别是什么,以便我可以使用相同的质量时,保存调整大小的图像?
  2. 这重要吗?我应该保存所有的图像在一个体面的水平(如: 75-80) ,无论原始质量?

我对此并不确定,因为我认为: (让我们举一个极端的例子) ,如果有人将一张500万像素的图像保存为质量为0,它将是块状的。减少图像大小为640x480,块状将被平滑和 勉强吧不太明显... 直到我保存它的质量为0再次..。

在光谱的另一端,如果有一个图像是800x600,q = 0,调整大小到640x480不会改变它看起来像废物的事实,所以用 q = 80保存将是多余的。

我说得对吗?

如果有用的话,我在 PHP 上使用 GD2库

48268 次浏览

Every new save of the file will further decrease overall quality, by using higher quality values you will preserve more of image. Regardless of what original image quality was.

  1. JPEG is a lossy format. Every time you save a JPEG same image, regardless of quality level, you will reduce the actual image quality. Therefore even if you did obtain a quality level from the file, you could not maintain that same quality when you save a JPEG again (even at quality=100).

  2. You should save your JPEG at as high a quality as you can afford in terms of file size. Or use a loss-less format such as PNG.

Low quality JPEG files do not simply become more blocky. Instead colour depth is reduced and the detail of sections of the image are removed. You can't rely on lower quality images being blocky and looking ok at smaller sizes.

According to the JFIF spec. the quality number (0-100) is not stored in the image header, although the horizontal and vertical pixel density is stored.

If you resave a JPEG using the same software that created it originally, using the same settings, you'll find that the damage is minimized - the algorithm will tend to throw out the same information it threw out the first time. I don't think there's any way to know what level was selected just by looking at the file; even if you could, different software almost guarantees different parameters and rounding, making a match almost impossible.

Jpeg compression algorithm has some parameters which influence on the quality of the result image.

One of such parameters are quantization tables which defines how many bits will be used on each coefficient. Different programs use different quatization tables.

Some programs allow user to set quality level 0-100. But there is no common defenition of this number. The image made with Photoshop with 60% quality takes 46 KB, while the image made with GIMP takes only 26 KB.

Quantization tables are also different.

There are other parameters such subsampling, dct method and etc.

So you can't describe all of them by single quality level number and you can't compare quality of jpeg images by single number. But you can create such number like photoshop or gimp which will describe compromiss between size on quality.

More information: http://patrakov.blogspot.com/2008/12/jpeg-quality-is-meaningless-number.html

Common practice is that you resize the image to appropriate size and apply jpeg after that. In this case huge and middle images will have the same size and quality.

This may be a silly question, but why would you be concerned about micromanaging the quality of the document? I believe if you use ImageMagick to do the conversion, it will manage the quality of the JPEG for you for best effect. http://www.php.net/manual/en/intro.imagick.php

So, there are basically two cases you care about:

  1. If an incoming image has quality set too high, it may take up an inappropriate amount of space. Therefore, you might want, for example, to reduce incoming q=99 to q=85.

  2. If an incoming image has quality set too low, it might be a waste of space to raise it's quality. Except that an image that's had a large amount of data discarded won't magically take up more space when the quality is raised -- blocky images will compress very nicely even at high quality settings. So, in my opinion it's perfectly OK to raise incoming q=1 to q=85.

From this I would think simply forcing a decent quality setting is a perfectly acceptable thing to do.

You can view compress level using the identify tool in ImageMagick. Download and installation instructions can be found at the official website.

After you install it, run the following command from the command line:

identify -format '%Q' yourimage.jpg

This will return a value from 0 (low quality, small filesize) to 100 (high quality, large filesize).

Information source

Here is a formula I've found to work well:

  1. jpg100size (the size it should not exceed in bytes for 98-100% quality) = width*height/1.7

  2. jpgxsize = jpg100size*x (x = percent, e.g. 0.65)

so, you could use these to find out statistically what quality your jpg was last saved at. if you want to get it down to let's say 65% quality and if you want to avoid resampling, you should compare the size initially to make sure it's not already too low, and only then reduce the quality

For future visitors, checking the quality of a given jpeg, you could just use imagemagick tooling:

$> identify -format '%Q' filename.jpg
92%

As there are already two answers using identify, here's one that also outputs the file name (for scanning multiple files at once):

If you wish to have a simple output of filename: quality for use on multiple images, you can use

identify -format '%f: %Q' *

to show the filename + compression of all files within the current directory.

Here are some ways to achieve your (1) and get it right.

  1. There are ways to do this by fitting to the quantization tables. Sherloq - for example - does this:

    https://github.com/GuidoBartoli/sherloq

    The relevant (python) code is at https://github.com/GuidoBartoli/sherloq/blob/master/gui/quality.py

  2. There is another algorithm written up in https://arxiv.org/abs/1802.00992 - you might consider contacting the author for any code etc.

  3. You can also simulate file_size(image_dimensions,quality_level) and then invert that function/lookup table to get quality_level(image_dimensions,file_size). Hey presto!

  4. Finally, you can adopt a brute-force https://en.wikipedia.org/wiki/Error_level_analysis approach by calculating the difference between the original image and recompressed versions each saved at a different quality level. The quality level of the original is roughly the one for which the difference is minimized. Seems to work reasonably well (but is linear in the for-loop..).

Most often the quality factor used seems to be 75 or 95 which might help you to get to the result faster. Probably no-one would save a JPEG at 100. Probably no-one would usefully save it at < 60 either.

I can add other links for this as they become available - please put them in the comments.

If you trust Irfanview estimation of JPEG compression level you can extract that information from the info text file created by the following Windows line command (your path to i_view32.exe might be different):

"C:\Program Files (x86)\IrfanView\i_view32.exe" <image-file> /info=txtfile

Jpg compression level is recorded in the IPTC data of an image.

Use exiftool (it's free) to get the exif data of an image then do a search on the returned string for "Photoshop Quality". Or at least put the data returned into a text document and check to see what's recorded. It may vary depending on the software used to save the image.

"Writer Name : Adobe Photoshop Reader Name : Adobe Photoshop CS6 Photoshop Quality : 7"