I personally let GD do the work. Here's an excerpt from one of my image classes.
function thumbnails($source, $quality, $thumb){
$this->source = $source;
$this->quality = $quality;
$this->thumb = $thumb;
if((!$this->quality) || ($this->quality < 0)){
$this->quality = 75;
}
$size = getimagesize($this->source);
if(($size[0] >= 1000) || ($size[1] >= 640)){
$scale = 2; //50% scale
} elseif(($size[0] >= 500) || ($size[1] >= 320)) {
$scale = 1; //0% scale
} elseif(($size[0] <= 150) || ($size[1] <= 100)) {
$scale = .5;
} else {
$scale = 1; //No scaling
}
if($this->thumb == "N"){
$w = $size[0] / $scale; // Width divided
$h = $size[1] / $scale; // Height divided
} else {
$w = 100;//thumbnail size
$h = 80;//thumbnail size
}
$resize = imagecreatetruecolor($w, $h); // Create a blank image
/* Check quality option. If quality is greater than 100, return error */
if ($this->quality > 100) {
$msg = 'The maximum quality is 100. Quality changes only affect JPEG images.';
return $msg;
} else {
switch ($size['mime']) {
case 'image/jpeg':
$im = imagecreatefromjpeg($this->source);
imagecopyresampled($resize, $im, 0, 0, 0, 0, $w, $h, $size[0], $size[1]); // Resample the original JPEG
imagejpeg($resize, $this->source, $this->quality); // Output the new JPEG
break;
case 'image/jpg':
$im = imagecreatefromjpeg($this->source);
imagecopyresampled($resize, $im, 0, 0, 0, 0, $w, $h, $size[0], $size[1]); // Resample the original JPEG
imagejpeg($resize, $this->source, $this->quality); // Output the new JPEG
break;
case 'image/png':
$im = imagecreatefrompng($this->source);
imagecopyresampled($resize, $im, 0, 0, 0, 0, $w, $h, $size[0], $size[1]); // Resample the original PNG
imagepng($resize, $this->source, $this->quality); // Output the new PNG
break;
}
imagedestroy($im);
return true;
}
}//end thumbnails function
I use them like this too:
$this->thumbnails($this->path.$this->image, $this->quality, "N");//not a thumb
$this->thumbnails($this->path."thumb_".$this->image, $this->quality, "Y"); // is a thumb