Detect JPEG image quality

后端 未结 7 897
借酒劲吻你
借酒劲吻你 2021-02-10 10:25

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 mo

相关标签:
7条回答
  • 2021-02-10 10:35

    For those who are using GraphicsMagick instead of ImageMagick, you can get the JPEG quality with the following command:

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

    and according to the documentation http://www.graphicsmagick.org/GraphicsMagick.html#details-format

    Please note that JPEG has no notion of "quality" and that the quality metric used by, and estimated by the software is based on the quality metric established by IJG JPEG 6b. Other encoders (e.g. that used by Adobe Photoshop) use different encoding metrics.

    0 讨论(0)
  • 2021-02-10 10:44

    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: rafaelkarst@gmail.com

    0 讨论(0)
  • 2021-02-10 10:48

    Here is a PHP function that tries all available methods of getting quality (that I know of):

    /* 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);
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-10 10:52

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

    $img = new Imagick($filename);
    $quality = $img->getImageCompressionQuality();
    
    0 讨论(0)
  • 2021-02-10 10:53

    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.

    0 讨论(0)
  • 2021-02-10 10:56

    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.

    0 讨论(0)
提交回复
热议问题