<?php/*** Thumbnail class.** @author Tamlyn Rhodes <tam at zenology dot co dot uk>* @license http://opensource.org/licenses/gpl-license.php GNU General Public License* @copyright (c)2003-2005 Tamlyn Rhodes* @version $Id: thumbnail.class.php,v 1.13 2006/06/24 20:33:00 tamlyn Exp $*//*** Creates and manages image thumbnails* @package singapore* @author Tamlyn Rhodes <tam at zenology dot co dot uk>* @copyright (c)2003-2005 Tamlyn Rhodes*/class sgThumbnail{var $config;var $maxWidth = 0;var $maxHeight = 0;var $thumbWidth = 0;var $thumbHeight = 0;var $cropWidth = 0;var $cropHeight = 0;var $forceSize = false;var $imagePath = "";var $thumbPath = "";function sgThumbnail(&$img, $type){$this->config =& sgConfig::getInstance();$this->image =& $img;$widthVar = "thumb_width_".$type;$heightVar = "thumb_height_".$type;$cropVar = "thumb_crop_".$type;$this->maxWidth = $this->config->$widthVar;$this->maxHeight = $this->config->$heightVar;if(isset($this->config->$cropVar))$this->forceSize = $this->config->$cropVar;if($this->image == null) return;$this->imagePath = $this->image->realPath();$this->thumbPath = $this->config->base_path.Singapore::thumbnailPath($this->image->parent->id, $this->image->id, $this->maxWidth, $this->maxHeight, $this->forceSize);$this->thumbURL = $this->config->base_url .Singapore::thumbnailPath($this->image->parent->id, $this->image->id, $this->maxWidth, $this->maxHeight, $this->forceSize);//security check: make sure requested file is in galleries directoryif(!Singapore::isSubPath($this->config->base_path.$this->config->pathto_galleries, $this->imagePath) && !$this->image->isRemote())return;//security check: make sure $image has a valid extensionif(!$this->image->isRemote() && !preg_match("/.+\.(".$this->config->recognised_extensions.")$/i",$this->image->id))return;$this->calculateDimensions();//link straight to image if it smaller than required sizeif($this->image->width <= $this->thumbWidth && $this->image->height <= $this->thumbHeight) {$this->thumbURL = $this->image->realURL();return;}$imageModified = @filemtime($this->imagePath);$thumbModified = @filemtime($this->thumbPath);if($imageModified > $thumbModified || !$thumbModified)$this->buildThumbnail();}/** Accessor methods */function width() { return $this->thumbWidth; }function height() { return $this->thumbHeight; }function URL() { return $this->thumbURL; }/** Private methods *//*** Calculates thumbnail dimensions.*/function calculateDimensions(){//if aspect ratio is to be constrained set crop sizeif($this->forceSize) {$newAspect = $this->maxWidth/$this->maxHeight;$oldAspect = $this->image->realWidth()/$this->image->realHeight();if($newAspect > $oldAspect) {$this->cropWidth = $this->image->realWidth();$this->cropHeight = round($this->image->realHeight()*($oldAspect/$newAspect));} else {$this->cropWidth = round($this->image->realWidth()*($newAspect/$oldAspect));$this->cropHeight = $this->image->realHeight();}//else crop size is image size} else {$this->cropWidth = $this->image->realWidth();$this->cropHeight = $this->image->realHeight();}if($this->cropHeight > $this->maxHeight && ($this->cropWidth <= $this->maxWidth|| ($this->cropWidth > $this->maxWidth && round($this->cropHeight/$this->cropWidth * $this->maxWidth) > $this->maxHeight))) {$this->thumbWidth = round($this->cropWidth/$this->cropHeight * $this->maxHeight);$this->thumbHeight = $this->maxHeight;} elseif($this->cropWidth > $this->maxWidth) {$this->thumbWidth = $this->maxWidth;$this->thumbHeight = round($this->cropHeight/$this->cropWidth * $this->maxWidth);} else {$this->thumbWidth = $this->image->realWidth();$this->thumbHeight = $this->image->realHeight();}}function buildThumbnail() {//set cropping offset$cropX = floor(($this->image->width-$this->cropWidth)/2);$cropY = floor(($this->image->height-$this->cropHeight)/2);//check thumbs directory exists and create it if notif(!file_exists(dirname($this->thumbPath)))Singapore::mkdir(dirname($this->thumbPath));//if file is remote then copy locally firstif($this->image->isRemote()) {$ip = @fopen($this->imagePath, "rb");$tp = @fopen($this->thumbPath, "wb");if($ip && $tp) {while(fwrite($tp,fread($ip, 4095)));fclose($tp);fclose($ip);$this->imagePath = $this->thumbPath;}}switch($this->config->thumbnail_software) {case "im" : //use ImageMagick v5.x$cmd = '"'.$this->config->pathto_convert.'"';if($this->forceSize) $cmd .= " -crop {$this->cropWidth}x{$this->cropHeight}+{$this->cropX}+{$this->cropY}";$cmd .= " -geometry {$this->thumbWidth}x{$this->thumbHeight}";if($this->image->type == 2) $cmd .= " -quality ".$this->config->thumbnail_quality;if($this->config->progressive_thumbs) $cmd .= " -interlace Plane";if($this->config->remove_jpeg_profile) $cmd .= ' +profile "*"';$cmd .= ' '.escapeshellarg($this->imagePath).' '.escapeshellarg($this->thumbPath);exec($cmd);break;case "im6" : //use ImageMagick v6.x$cmd = '"'.$this->config->pathto_convert.'"';$cmd .= ' '.escapeshellarg($this->imagePath);if($this->config->progressive_thumbs) $cmd .= " -interlace Plane";if($this->image->type == 2) $cmd .= " -quality ".$this->config->thumbnail_quality;if($this->forceSize) $cmd .= " -crop {$this->cropWidth}x{$this->cropHeight}+{$this->cropX}+{$this->cropY}";$cmd .= " -resize {$this->thumbWidth}x{$this->thumbHeight}";if($this->config->remove_jpeg_profile) $cmd .= ' +profile "*"';$cmd .= ' '.escapeshellarg($this->thumbPath);exec($cmd);break;case "gd2" :case "gd1" :default : //use GD by default//read in image as appropriate typeswitch($this->image->type) {case 1 : $image = ImageCreateFromGIF($this->imagePath); break;case 3 : $image = ImageCreateFromPNG($this->imagePath); break;case 2 :default: $image = ImageCreateFromJPEG($this->imagePath); break;}if($image) {switch($this->config->thumbnail_software) {case "gd2" ://create blank truecolor image$thumb = ImageCreateTrueColor($this->thumbWidth,$this->thumbHeight);//resize image with resamplingImageCopyResampled($thumb, $image,0, 0, $cropX, $cropY,$this->thumbWidth, $this->thumbHeight, $this->cropWidth, $this->cropHeight);break;case "gd1" :default ://create blank 256 color image$thumb = ImageCreate($this->thumbWidth,$this->thumbHeight);//resize imageImageCopyResized($thumb, $image,0, 0, $cropX, $cropY,$this->thumbWidth, $this->thumbHeight, $this->cropWidth, $this->cropHeight);break;}} /*else {$thumb = ImageCreate($this->thumbWidth, $this->thumbHeight);$bg = ImageColorAllocate($thumb, 255, 255, 255);$text = ImageColorAllocate($thumb, 255, 0, 0);ImageString($thumb, 1, 0, 0, "Cannot load source image", $text);}*///set image interlacing@ImageInterlace($thumb, $this->config->progressive_thumbs);//output image of appropriate typeswitch($this->image->type) {case 1 ://GIF images are saved as PNGcase 3 :ImagePNG($thumb, $this->thumbPath);break;case 2 :default:ImageJPEG($thumb, $this->thumbPath, $this->config->thumbnail_quality);break;}@ImageDestroy($image);@ImageDestroy($thumb);}//set file permissions on newly created thumbnail@chmod($this->thumbPath, octdec($this->config->file_mode));}}?>