Decent autogen thumbnail script but has a bug

Hello, I have found a decent auto generating thumbnail script on the net and I’ve had it stored for a long time without really paying any attention to it. So the other day I ran it out of curiosity to see if it worked. It did and does a good job however it produces very poor quality thumbnail photos.

Does anyone have any idea why this is and how to fix it? I have been looking into the functions from the manual on the main PHP website but am lost as to why I can’t get the quality to improve. The line I have zeroed in on was line 79 where it states:

imagejpeg($dst_img, $filename, 100);  

Since imagejpeg is the only function that takes quality into consideration, I added 100 here. I know by default, and without a number, it uses 75 as a quality. However, in this script, changing this number does nothing for me and the thumbnails are still terrible. Any insight is appreciated.

I am running the 2.0.34 compatible version of the GD library from the PHP 5.3.0 install in a WAMP environment.

Thank you!

Have two folders created and named pics and [B]thumbs

pics[/B] is where the fullsize photos reside. Leave thumbs blank as the script will populate it on runtime.

<?php 
$gd2=checkgd();
$pics=directory("pics","jpg,JPG,JPEG,jpeg,png,PNG");
$pics=ditchtn($pics,"tn_");
if ($pics[0]!=""){
    foreach ($pics as $p){
        createthumb("pics/".$p,"thumbs/tn_".$p,100,100);
    }
}
/*
    Function checkgd()
    checks the version of gd, and returns "yes" when it's higher than 2
*/
function checkgd(){
    $gd2="";
    ob_start();
    phpinfo(8);
    $phpinfo=ob_get_contents();
    ob_end_clean();
    $phpinfo=strip_tags($phpinfo);
    $phpinfo=stristr($phpinfo,"gd version");
    $phpinfo=stristr($phpinfo,"version");
    $end=strpos($phpinfo," ");
    $phpinfo=substr($phpinfo,0,$end);
    $phpinfo=substr($phpinfo,7);
    if (preg_match("/2./",$phpinfo)){$gd2="yes";}
    return $gd2;
}

/*
    Function ditchtn($arr,$thumbname)
    filters out thumbnails
*/
function ditchtn($arr,$thumbname){
    foreach ($arr as $item){
        if (!preg_match("/^".$thumbname."/",$item)){$tmparr[]=$item;}
    }
    return $tmparr;
}

/*
    Function createthumb($name,$filename,$new_w,$new_h)
    creates a resized image
    variables:
    $name        Original filename
    $filename    Filename of the resized image
    $new_w        width of resized image
    $new_h        height of resized image
*/    
function createthumb($name,$filename,$new_w,$new_h){
    global $gd2;
    $system=explode(".",$name);
    if (preg_match("/jpg|jpeg/",$system[1])){$src_img=imagecreatefromjpeg($name);}
    if (preg_match("/png/",$system[1])){$src_img=imagecreatefrompng($name);}
    $old_x=imageSX($src_img);
    $old_y=imageSY($src_img);
    if ($old_x > $old_y) {
        $thumb_w=$new_w;
        $thumb_h=$old_y*($new_h/$old_x);
    }
    if ($old_x < $old_y) {
        $thumb_w=$old_x*($new_w/$old_y);
        $thumb_h=$new_h;
    }
    if ($old_x == $old_y) {
        $thumb_w=$new_w;
        $thumb_h=$new_h;
    }
    if ($gd2==""){
            $dst_img=ImageCreate($thumb_w,$thumb_h);
            imagecopyresized($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y); 
    }else{
        $dst_img=ImageCreateTrueColor($thumb_w,$thumb_h);
        imagecopyresampled($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y); 
    }
    if (preg_match("/png/",$system[1])){
        imagepng($dst_img, $filename); 
    } else {
        imagejpeg($dst_img, $filename, 100); 
    }
    imagedestroy($dst_img); 
    imagedestroy($src_img); 
}

/*
        Function directory($directory,$filters)
        reads the content of $directory, takes the files that apply to $filter 
        and returns an array of the filenames.
        You can specify which files to read, for example
        $files = directory(".","jpg,gif");
                gets all jpg and gif files in this directory.
        $files = directory(".","all");
                gets all files.
*/
function directory($dir,$filters){
    $handle=opendir($dir);
    $files=array();
    if ($filters == "all"){while(($file = readdir($handle))!==false){$files[] = $file;}}
    if ($filters != "all"){
        $filters=explode(",",$filters);
        while (($file = readdir($handle))!==false) {
            for ($f=0;$f<sizeof($filters);$f++):
                $system=explode(".",$file);
                if ($system[1] == $filters[$f]){$files[] = $file;}
            endfor;
        }
    }
    closedir($handle);
    return $files;
}
?>

Hi Drew
change Imagecreate to imagecreatetruecolor and set the quality to 99 rather than 100 :slight_smile:

What are you using for input?

Hey there, thanks for the reply. Listen, I am out of my league here in terms of knowing what I THINK I am talking about so forgive me in advance because I don’t want to be construed as rude. But when I read through the comments in the script, I get the opinion that it is checking if you have GD v2 or not and if yes, then it uses the imagecreatetruecolor () and if not then it uses imagecreate(). However, I believe those functions are only part of the process and don’t actually make the image. Am I not correct in thinking that the imagejpeg () part deals with the quality settings?

if ($gd2==""){
            $dst_img=ImageCreate($thumb_w,$thumb_h);
            imagecopyresized($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y); 
    }else{
        $dst_img=ImageCreateTrueColor($thumb_w,$thumb_h);
        imagecopyresampled($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y); 
    }
    if (preg_match("/png/",$system[1])){
        imagepng($dst_img, $filename); 
    } else {
        imagejpeg($dst_img, $filename, 100); 
    }
    imagedestroy($dst_img); 
    imagedestroy($src_img); 
} 

Hello and thanks for your reply also. However I don’t understand the context of your question exactly. If you mean by input in terms of fullsize photos to thumbnail photos, the original size photos go inside the pics folder. Any number will do. Then if you run the script, it will process all the photos in pics folder to thumbnails inside the thumbs folder…

If I misunderstood your question, then I need more context to answer correctly.

Thanks!

Hmmmm, I am not sure the checkgd (); function works…that could be why its giving me poor thumbnails instead of true color thumbs. I have never used PHP to grab information from the phpinfo(); before so I think I’ll need to explore this further…I mean if it was working it should give me a value of 2 which is assigned “yes”. I have not been able to get any value yet…and that makes me think its defaulting to the imagecreate(); function.

function checkgd(){
    $gd2="";
    ob_start();
    phpinfo(8);
    $phpinfo=ob_get_contents();
    ob_end_clean();
    $phpinfo=strip_tags($phpinfo);
    $phpinfo=stristr($phpinfo,"gd version");
    $phpinfo=stristr($phpinfo,"version");
    $end=strpos($phpinfo," ");
    $phpinfo=substr($phpinfo,0,$end);
    $phpinfo=substr($phpinfo,7);
    if (preg_match("/2./",$phpinfo)){$gd2="yes";}
    return $gd2;
}

Possibly and its a round the houses way of checking. Something simpler like:


if (extension_loaded('gd') && function_exists('gd_info')) {
    echo "It looks like GD is installed";
}

would be better but that said, the chances of not having v2 as standard is unlikely.

You could risk it and take out the checking function and the if($gd2==“”) part.

so it would be


        $dst_img=imagecreatetruecolor($thumb_w,$thumb_h);
        imagecopyresampled($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y); 

Yup, that was it…excellent. Too bad though about the check part. When I get more time I will look into that. I like the idea of performing code based on information from the phpinfo (); function. Not that I have a need for it right now, but its a pretty cool train of thought.

See I liked this script because its 50X faster to create thumbnails locally instead of using Photoshop CS5 since Adobe took out some automation by default and moved it to Bridge. I really don’t use Bridge much and it takes too long to do thumbnails that way anyhow. This script is so much easier to use…

Thank you so much for being the second set of eyes I needed to work through this problem. Cheers SpikeZ!

No problem Drew.

One thing you might want to consider is imagemagick. For a particular project I am working on I needed to reprocess 20,000+ images into thumbnails and 800x800 and IM can do folders in one go.

Might be worth looking into if you are doing loads of reprocessing