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.
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 :-)
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;
}
}
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
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.