PHP GD Jpeg with a target filesize

2020-07-25 07:34发布

问题:

I'd like to feed PHP/GD an image resource and a target file size and have it output a JPEG file of that target size. Say, I have a 500KB PNG image that needs to be 100KB.

Example.

function target_image_filesize($im,$target_size){
  //create gd image
  //return a new image resource of specified size
}

I know I've seen a function for this floating around, and it's not something I'm looking to re-invent if possible.

回答1:

The trick will be in specifying proper JPEG quality. But this parameter is never defined, here you can read that:

In fact, quality scales aren't even standardized across JPEG programs.

But... there could be a clever solution! However a bit of work:

1) take few PNG images
2) convert them to JPEGs with with quality varying from (say) 50 to 100 by step 1
3) analyze the dependency between the quality and file size - is it quadratic: size ~ q * q, or exponential - size ~ x^q, or reciprocal - size ~ 1/q or whatever..?
4) build a general expression to predict file size from quality and vice versa
5) post the result here :-)



回答2:

If anyone else has this same problem, this should help.

function make_jpeg_target_size($file,$saveDir,$targetKB){
    $imageInfo = getimagesize($file);
    $filename = array_shift(explode('.',basename($file)));
    switch($imageInfo['mime']){
        case 'image/jpeg':
            $src = imagecreatefromjpeg($file);
            break;
        case 'image/gif':
            $src = imagecreatefromgif($file);
            break;
        case 'image/png':
            $src = imagecreatefrompng($file);
            break;
    }
    $target = $targetKB*1024;
    $start_q = 1;
    $cur_q = 99;
    while($cur_q > $start_q){
        $temp_file = tempnam(sys_get_temp_dir(), 'checksizer');
        $out = imagejpeg($src, $temp_file, $cur_q);
        $size = filesize($temp_file);
        if($size <= $target){
            $s = $targetKB.'kb';
            $saveAs = str_replace("//","/",$saveDir.'/'.$filename.'-'.$s.'.jpg');
            copy($temp_file, $saveAs);
            unlink($temp_file);
            $cur_q=0;
        }
        $cur_q=$cur_q-1;
    }
    if($saveAs == ''){
        return false;
    }else{
        return $saveAs;
    }
}


回答3:

If you have access to the command line, I recommend to use http://www.imagemagick.org it is very fast. We use it in our similar application. in php - system('convert ...'); or php lib http://php.net/manual/en/book.imagick.php

GD is quite slow and we had problems with it



回答4:

The filesize of a jpeg isn't just dependent on the save quality and resolution. If you have an image thats a solid color, and a photograph - they will be different file sizes because of how jpeg compression works. Unfortunately you'll have to generate it, test filesize, and then determine if you need to re-generate.



标签: php gd