Detect JPEG image quality

11,878

Solution 1

paddy is correct that this setting is not always stored in the JPEG file. If it is, then you can use identify from Imagemagick to read the quality. For example:

$ identify -format '%Q' tornado_ok.jpg

93%

Update: Based on the answer to this question https://superuser.com/questions/62730/how-to-find-the-jpg-quality I find out that apparently the identify command can still determine the quality by reverse engineering the quantization tables even if all the image EXIF / other meta data is lost. By the way, the title of your question as it stands now is a possible duplicate of that question I linked to.

But to me your question has merit on its own because in your question's text you explain what you are trying to do, which is more than simply detecting jpeg quality. Nevertheless, you should perhaps update the title if you want to reflect that you are trying to solve a more specific problem than just reading JPEG image quality.

Unless you are archiving original images, for web use even 90% is excessive. 75% used to be the default in the old days (degradation was visible only under close inspection between side-by-side images), and now in the days of high bandwidth 85% is a very high quality option. The 5% quality difference between 90% and 85% is virtually invisible, but will save you over 30% in file size typically. The JPEG algorithm is designed to begin by eliminating information that is invisible to human perception at its first compression stages (above 80% or so).

Update/note: The compression quality settings I am talking about are from tests with libjpeg, a very widely used JPEG library. Photoshop's compression percentages and other software's quality settings are all independent and do not necessarily mean the same thing as the settings of libjpeg.

paddy's idea of using image height and image width to calculate an acceptable file size is reasonable:

You can get the image height/width like this:

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

My own high-quality photos posted online, like this one: http://ksathletics.com/2013/wsumbb/nw.jpg are typically saved at a ratio of about 200 KB per megapixel.

So, for example, you can multiply width times height and divide by 1000000 to calculate the megapixels in the image. Divide the file size by 1024 to calculate the KB. Then divide the resulting KB by the megapixels. If the result is under 200 or whatever value you decide upon, then you don't need to re-compress it. Otherwise, you can re-compress it with a quality of 85% or whatever quality you decide on.

Solution 2

Since the OP stated he prefers php, I offer the following:

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

Solution 3

whats up? I was facing the same problem with an app I'm developing... My problem is that, I extract several images from a random site and each item have several images, i would like to show a single image for each item, and bring to the user the best quality image.

I came out with this idea, its pretty simple, and will work for any language and any type of compression:

//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);

I ran this algorithm against the http://fotoforensics.com/tutorial-estq.php mentioned above and here are the results:

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

The basic idea behind this algorithm is compare the size that an image could reach if written in a bitmap way (without any compression, 3 bytes per pixel, 3 bytes for RGB) to the size that this image is currently using. The smaller is the image size, the higher is the compression, independently of the compression method used, rather its a JPG, a PNG or whatever, and that will lead us into having a bigger gap or smaller gap between uncompressed and compressed image.

It is also important to mention, that this is a mathematical solution for comparison purposes, this method will not return the actually quality of the image, it will answer the distance percentage between uncompressed and compressed sizes!

if you need more details, you can send me an email: [email protected]

Solution 4

You cannot guarantee that the quality setting is stored in the JPEG's metadata. This is an encoder setting, not an image attribute.

Read more here about estimating JPEG quality

It might make more sense to simply define a maximum file size. At the end of the day, restricting image quality is all about saving bandwidth. So setting a ratio between image dimensions and file size is more appropriate.

Solution 5

If your jpeg was created using a straight scaling of the standard image quantization tables and the 0-100 quality was used based on the Independent JPEG Group's formula, then, assuming you have the luminance quantization tables in an array called quantization (such as Python's PIL module provides in image.quantization[0]), then the original value can be obtained via:

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

Basically, the default luminance quantization value #15 is 40 and #58 is 100, so these make handy values to extract the results from. IJG scales values about 50 via 5000 / Q and below 50 via 200 - 2 * Q. If the quality setting is less than 8, this won't give decent results (if quantization[5] == 255) -- in that case, perhaps use quantization table position #5

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

Share:
11,878
jcisio
Author by

jcisio

Drupal developer. FOSS user.

Updated on July 28, 2022

Comments

  • jcisio
    jcisio almost 2 years

    I allow users to upload images. However, I want to keep JPEG quality not more than 90%. What I plan to do is to detect the current quality: - If less than 90% do nothing - If more than 90%, than use Image Magick to recompress the image to 90%

    Is it possible to do that? I prefer PHP but any language will help.

  • jcisio
    jcisio almost 11 years
    In fact my current quality settings is 85% but a few contributors even say that it's ugly. Because I don't archive original image, I need a quite high quality (for derivative images, like thumbnails, I use a lower quality). Use the dimension/size rate as the threshold sounds reasonable. I'm choosing your answer because it's well explained. Thanks.
  • jcisio
    jcisio almost 11 years
    I appreciate your answer. I hesistate to decide about accepting it. I chose Joseph's one because it's well explained in his long answer. Thanks.
  • unidentified-1
    unidentified-1 almost 7 years
    Brilliant. Thank you.
  • rosell.dk
    rosell.dk almost 6 years
    The correct format option isn't '%[JPEG-Quality]', but '%Q'. So it would be: gm identify -format '%Q' path_to/image_file.jpg