[Phpslash-commit] CVS: phpslash-dev/public_html/scripts/htmlarea3/plugins/ImageManager/Classes Files
Brought to you by:
joestewart,
nhruby
From: Joe S. <joe...@us...> - 2004-08-23 17:49:18
|
Update of /cvsroot/phpslash/phpslash-dev/public_html/scripts/htmlarea3/plugins/ImageManager/Classes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6597/phpslash-dev/public_html/scripts/htmlarea3/plugins/ImageManager/Classes Added Files: Files.php GD.php IM.php ImageEditor.php ImageManager.php NetPBM.php Thumbnail.php Transform.php Log Message: Upgraded htmlarea2 --- NEW FILE: Files.php --- <? /** * File Utilities. * @author $Author: joestewart $ * @version $Id: Files.php,v 1.1 2004/08/23 17:48:59 joestewart Exp $ * @package ImageManager */ define('FILE_ERROR_NO_SOURCE', 100); define('FILE_ERROR_COPY_FAILED', 101); define('FILE_ERROR_DST_DIR_FAILED', 102); define('FILE_COPY_OK', 103); /** * File Utilities * @author $Author: joestewart $ * @version $Id: Files.php,v 1.1 2004/08/23 17:48:59 joestewart Exp $ * @package ImageManager * @subpackage files */ class Files { /** * Copy a file from source to destination. If unique == true, then if * the destination exists, it will be renamed by appending an increamenting * counting number. * @param string $source where the file is from, full path to the files required * @param string $destination_file name of the new file, just the filename * @param string $destination_dir where the files, just the destination dir, * e.g., /www/html/gallery/ * @param boolean $unique create unique destination file if true. * @return string the new copied filename, else error if anything goes bad. */ function copyFile($source, $destination_dir, $destination_file, $unique=true) { if(!(file_exists($source) && is_file($source))) return FILE_ERROR_NO_SOURCE; $destination_dir = Files::fixPath($destination_dir); if(!is_dir($destination_dir)) Return FILE_ERROR_DST_DIR_FAILED; $filename = Files::escape($destination_file); if($unique) { $dotIndex = strrpos($destination_file, '.'); $ext = ''; if(is_int($dotIndex)) { $ext = substr($destination_file, $dotIndex); $base = substr($destination_file, 0, $dotIndex); } $counter = 0; while(is_file($destination_dir.$filename)) { $counter++; $filename = $base.'_'.$counter.$ext; } } if (!copy($source, $destination_dir.$filename)) return FILE_ERROR_COPY_FAILED; //verify that it copied, new file must exists if (is_file($destination_dir.$filename)) Return $filename; else return FILE_ERROR_COPY_FAILED; } /** * Create a new folder. * @param string $newFolder specifiy the full path of the new folder. * @return boolean true if the new folder is created, false otherwise. */ function createFolder($newFolder) { mkdir ($newFolder, 0777); return chmod($newFolder, 0777); } /** * Escape the filenames, any non-word characters will be * replaced by an underscore. * @param string $filename the orginal filename * @return string the escaped safe filename */ function escape($filename) { Return preg_replace('/[^\w\._]/', '_', $filename); } /** * Delete a file. * @param string $file file to be deleted * @return boolean true if deleted, false otherwise. */ function delFile($file) { if(is_file($file)) Return unlink($file); else Return false; } /** * Delete folder(s), can delete recursively. * @param string $folder the folder to be deleted. * @param boolean $recursive if true, all files and sub-directories * are delete. If false, tries to delete the folder, can throw * error if the directory is not empty. * @return boolean true if deleted. */ function delFolder($folder, $recursive=false) { $deleted = true; if($recursive) { $d = dir($folder); while (false !== ($entry = $d->read())) { if ($entry != '.' && $entry != '..') { $obj = Files::fixPath($folder).$entry; //var_dump($obj); if (is_file($obj)) { $deleted &= Files::delFile($obj); } else if(is_dir($obj)) { $deleted &= Files::delFolder($obj, $recursive); } } } $d->close(); } //$folder= $folder.'/thumbs'; //var_dump($folder); if(is_dir($folder)) $deleted &= rmdir($folder); else $deleted &= false; Return $deleted; } /** * Append a / to the path if required. * @param string $path the path * @return string path with trailing / */ function fixPath($path) { //append a slash to the path if it doesn't exists. if(!(substr($path,-1) == '/')) $path .= '/'; Return $path; } /** * Concat two paths together. Basically $pathA+$pathB * @param string $pathA path one * @param string $pathB path two * @return string a trailing slash combinded path. */ function makePath($pathA, $pathB) { $pathA = Files::fixPath($pathA); if(substr($pathB,0,1)=='/') $pathB = substr($pathB,1); Return Files::fixPath($pathA.$pathB); } /** * Similar to makePath, but the second parameter * is not only a path, it may contain say a file ending. * @param string $pathA the leading path * @param string $pathB the ending path with file * @return string combined file path. */ function makeFile($pathA, $pathB) { $pathA = Files::fixPath($pathA); if(substr($pathB,0,1)=='/') $pathB = substr($pathB,1); Return $pathA.$pathB; } /** * Format the file size, limits to Mb. * @param int $size the raw filesize * @return string formated file size. */ function formatSize($size) { if($size < 1024) return $size.' bytes'; else if($size >= 1024 && $size < 1024*1024) return sprintf('%01.2f',$size/1024.0).' Kb'; else return sprintf('%01.2f',$size/(1024.0*1024)).' Mb'; } } ?> --- NEW FILE: GD.php --- <?php /*********************************************************************** ** Title.........: GD Driver ** Version.......: 1.0 ** Author........: Xiang Wei ZHUO <we...@zh...> ** Filename......: GD.php ** Last changed..: 30 Aug 2003 ** Notes.........: Orginal is from PEAR **/ // +----------------------------------------------------------------------+ // | PHP Version 4 | // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2002 The PHP Group | // +----------------------------------------------------------------------+ // | This source file is subject to version 2.02 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | // | available at through the world-wide-web at | // | http://www.php.net/license/2_02.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | li...@ph... so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ // | Authors: Peter Bowyer <pe...@ma...> | // | Alan Knowles <al...@ak...> | // +----------------------------------------------------------------------+ // // Usage : // $img = new Image_Transform_GD(); // $angle = -78; // $img->load('magick.png'); // // if($img->rotate($angle,array('autoresize'=>true,'color_mask'=>array(255,0,0)))){ // $img->addText(array('text'=>"Rotation $angle",'x'=>0,'y'=>100,'font'=>'/usr/share/fonts/default/TrueType/cogb____.ttf')); // $img->display(); // } else { // echo "Error"; // } // // // $Id: GD.php,v 1.1 2004/08/23 17:48:59 joestewart Exp $ // // Image Transformation interface using the GD library // require_once "Transform.php"; Class Image_Transform_Driver_GD extends Image_Transform { /** * Holds the image file for manipulation */ var $imageHandle = ''; /** * Holds the original image file */ var $old_image = ''; /** * Check settings * * @return mixed true or or a PEAR error object on error * * @see PEAR::isError() */ function Image_Transform_GD() { return; } // End function Image /** * Load image * * @param string filename * * @return mixed none or a PEAR error object on error * @see PEAR::isError() */ function load($image) { $this->uid = md5($_SERVER['REMOTE_ADDR']); $this->image = $image; $this->_get_image_details($image); $functionName = 'ImageCreateFrom' . $this->type; if(function_exists($functionName)) { $this->imageHandle = $functionName($this->image); } } // End load /** * addText * * @param array options Array contains options * array( * 'text' The string to draw * 'x' Horizontal position * 'y' Vertical Position * 'Color' Font color * 'font' Font to be used * 'size' Size of the fonts in pixel * 'resize_first' Tell if the image has to be resized * before drawing the text * ) * * @return none * @see PEAR::isError() */ function addText($params) { $default_params = array( 'text' => 'This is Text', 'x' => 10, 'y' => 20, 'color' => array(255,0,0), 'font' => 'Arial.ttf', 'size' => '12', 'angle' => 0, 'resize_first' => false // Carry out the scaling of the image before annotation? Not used for GD ); $params = array_merge($default_params, $params); extract($params); if( !is_array($color) ){ if ($color[0]=='#'){ $this->colorhex2colorarray( $color ); } else { include_once('Image/Transform/Driver/ColorsDefs.php'); $color = isset($colornames[$color])?$colornames[$color]:false; } } $c = imagecolorresolve ($this->imageHandle, $color[0], $color[1], $color[2]); if ('ttf' == substr($font, -3)) { ImageTTFText($this->imageHandle, $size, $angle, $x, $y, $c, $font, $text); } else { ImagePSText($this->imageHandle, $size, $angle, $x, $y, $c, $font, $text); } return true; } // End addText /** * Rotate image by the given angle * Uses a fast rotation algorythm for custom angles * or lines copy for multiple of 90 degrees * * @param int $angle Rotation angle * @param array $options array( 'autoresize'=>true|false, * 'color_mask'=>array(r,g,b), named color or #rrggbb * ) * @author Pierre-Alain Joye * @return mixed none or a PEAR error object on error * @see PEAR::isError() */ function rotate($angle, $options=null) { if(function_exists('imagerotate')) { $white = imagecolorallocate ($this->imageHandle, 255, 255, 255); $this->imageHandle = imagerotate($this->imageHandle, $angle, $white); return true; } if ( $options==null ){ $autoresize = true; $color_mask = array(255,255,0); } else { extract( $options ); } while ($angle <= -45) { $angle += 360; } while ($angle > 270) { $angle -= 360; } $t = deg2rad($angle); if( !is_array($color_mask) ){ if ($color[0]=='#'){ $this->colorhex2colorarray( $color_mask ); } else { include_once('Image/Transform/Driver/ColorDefs.php'); $color = isset($colornames[$color_mask])?$colornames[$color_mask]:false; } } // Do not round it, too much lost of quality $cosT = cos($t); $sinT = sin($t); $img =& $this->imageHandle; $width = $max_x = $this->img_x; $height = $max_y = $this->img_y; $min_y = 0; $min_x = 0; $x1 = round($max_x/2,0); $y1 = round($max_y/2,0); if ( $autoresize ){ $t = abs($t); $a = round($angle,0); switch((int)($angle)){ case 0: $width2 = $width; $height2 = $height; break; case 90: $width2 = $height; $height2 = $width; break; case 180: $width2 = $width; $height2 = $height; break; case 270: $width2 = $height; $height2 = $width; break; default: $width2 = (int)(abs(sin($t) * $height + cos($t) * $width)); $height2 = (int)(abs(cos($t) * $height+sin($t) * $width)); } $width2 -= $width2%2; $height2 -= $height2%2; $d_width = abs($width - $width2); $d_height = abs($height - $height2); $x_offset = $d_width/2; $y_offset = $d_height/2; $min_x2 = -abs($x_offset); $min_y2 = -abs($y_offset); $max_x2 = $width2; $max_y2 = $height2; } $img2 = @imagecreate($width2,$height2); if ( !is_resource($img2) ){ return false;/*PEAR::raiseError('Cannot create buffer for the rotataion.', null, PEAR_ERROR_TRIGGER, E_USER_NOTICE);*/ } $this->img_x = $width2; $this->img_y = $height2; imagepalettecopy($img2,$img); $mask = imagecolorresolve($img2,$color_mask[0],$color_mask[1],$color_mask[2]); // use simple lines copy for axes angles switch((int)($angle)){ case 0: imagefill ($img2, 0, 0,$mask); for ($y=0; $y < $max_y; $y++) { for ($x = $min_x; $x < $max_x; $x++){ $c = @imagecolorat ( $img, $x, $y); imagesetpixel($img2,$x+$x_offset,$y+$y_offset,$c); } } break; case 90: imagefill ($img2, 0, 0,$mask); for ($x = $min_x; $x < $max_x; $x++){ for ($y=$min_y; $y < $max_y; $y++) { $c = imagecolorat ( $img, $x, $y); imagesetpixel($img2,$max_y-$y-1,$x,$c); } } break; case 180: imagefill ($img2, 0, 0,$mask); for ($y=0; $y < $max_y; $y++) { for ($x = $min_x; $x < $max_x; $x++){ $c = @imagecolorat ( $img, $x, $y); imagesetpixel($img2, $max_x2-$x-1, $max_y2-$y-1, $c); } } break; case 270: imagefill ($img2, 0, 0,$mask); for ($y=0; $y < $max_y; $y++) { for ($x = $max_x; $x >= $min_x; $x--){ $c = @imagecolorat ( $img, $x, $y); imagesetpixel($img2,$y,$max_x-$x-1,$c); } } break; // simple reverse rotation algo default: $i=0; for ($y = $min_y2; $y < $max_y2; $y++){ // Algebra :) $x2 = round((($min_x2-$x1) * $cosT) + (($y-$y1) * $sinT + $x1),0); $y2 = round((($y-$y1) * $cosT - ($min_x2-$x1) * $sinT + $y1),0); for ($x = $min_x2; $x < $max_x2; $x++){ // Check if we are out of original bounces, if we are // use the default color mask if ( $x2>=0 && $x2<$max_x && $y2>=0 && $y2<$max_y ){ $c = imagecolorat ( $img, $x2, $y2); } else { $c = $mask; } imagesetpixel($img2,$x+$x_offset,$y+$y_offset,$c); // round verboten! $x2 += $cosT; $y2 -= $sinT; } } break; } $this->old_image = $this->imageHandle; $this->imageHandle = $img2; return true; } /** * Resize Action * * For GD 2.01+ the new copyresampled function is used * It uses a bicubic interpolation algorithm to get far * better result. * * @param $new_x int new width * @param $new_y int new height * * @return true on success or pear error * @see PEAR::isError() */ function _resize($new_x, $new_y) { if ($this->resized === true) { return false; /*PEAR::raiseError('You have already resized the image without saving it. Your previous resizing will be overwritten', null, PEAR_ERROR_TRIGGER, E_USER_NOTICE);*/ } if(function_exists('ImageCreateTrueColor')){ $new_img =ImageCreateTrueColor($new_x,$new_y); } else { $new_img =ImageCreate($new_x,$new_y); } if(function_exists('ImageCopyResampled')){ ImageCopyResampled($new_img, $this->imageHandle, 0, 0, 0, 0, $new_x, $new_y, $this->img_x, $this->img_y); } else { ImageCopyResized($new_img, $this->imageHandle, 0, 0, 0, 0, $new_x, $new_y, $this->img_x, $this->img_y); } $this->old_image = $this->imageHandle; $this->imageHandle = $new_img; $this->resized = true; $this->new_x = $new_x; $this->new_y = $new_y; return true; } /** * Crop the image * * @param int $crop_x left column of the image * @param int $crop_y top row of the image * @param int $crop_width new cropped image width * @param int $crop_height new cropped image height */ function crop($new_x, $new_y, $new_width, $new_height) { if(function_exists('ImageCreateTrueColor')){ $new_img =ImageCreateTrueColor($new_width,$new_height); } else { $new_img =ImageCreate($new_width,$new_height); } if(function_exists('ImageCopyResampled')){ ImageCopyResampled($new_img, $this->imageHandle, 0, 0, $new_x, $new_y,$new_width,$new_height,$new_width,$new_height); } else { ImageCopyResized($new_img, $this->imageHandle, 0, 0, $new_x, $new_y, $new_width,$new_height,$new_width,$new_height); } $this->old_image = $this->imageHandle; $this->imageHandle = $new_img; $this->resized = true; $this->new_x = $new_x; $this->new_y = $new_y; return true; } /** * Flip the image horizontally or vertically * * @param boolean $horizontal true if horizontal flip, vertical otherwise */ function flip($horizontal) { if(!$horizontal) { $this->rotate(180); } $width = imagesx($this->imageHandle); $height = imagesy($this->imageHandle); for ($j = 0; $j < $height; $j++) { $left = 0; $right = $width-1; while ($left < $right) { //echo " j:".$j." l:".$left." r:".$right."\n<br>"; $t = imagecolorat($this->imageHandle, $left, $j); imagesetpixel($this->imageHandle, $left, $j, imagecolorat($this->imageHandle, $right, $j)); imagesetpixel($this->imageHandle, $right, $j, $t); $left++; $right--; } } return true; } /** * Adjust the image gamma * * @param float $outputgamma * * @return none */ function gamma($outputgamma=1.0) { ImageGammaCorrect($this->imageHandle, 1.0, $outputgamma); } /** * Save the image file * * @param $filename string the name of the file to write to * @param $quality int output DPI, default is 85 * @param $types string define the output format, default * is the current used format * * @return none */ function save($filename, $type = '', $quality = 85) { $type = $type==''? $this->type : $type; $functionName = 'image' . $type; if(function_exists($functionName)) { $this->old_image = $this->imageHandle; if($type=='jpeg') $functionName($this->imageHandle, $filename, $quality); else $functionName($this->imageHandle, $filename); $this->imageHandle = $this->old_image; $this->resized = false; } } // End save /** * Display image without saving and lose changes * * @param string type (JPG,PNG...); * @param int quality 75 * * @return none */ function display($type = '', $quality = 75) { if ($type != '') { $this->type = $type; } $functionName = 'Image' . $this->type; if(function_exists($functionName)) { header('Content-type: image/' . strtolower($this->type)); $functionName($this->imageHandle, '', $quality); $this->imageHandle = $this->old_image; $this->resized = false; ImageDestroy($this->old_image); $this->free(); } } /** * Destroy image handle * * @return none */ function free() { if ($this->imageHandle){ ImageDestroy($this->imageHandle); } } } // End class ImageGD ?> --- NEW FILE: IM.php --- <?php /*********************************************************************** ** Title.........: ImageMagick Driver ** Version.......: 1.0 ** Author........: Xiang Wei ZHUO <we...@zh...> ** Filename......: IM.php ** Last changed..: 30 Aug 2003 ** Notes.........: Orginal is from PEAR **/ // +----------------------------------------------------------------------+ // | PHP Version 4 | // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2002 The PHP Group | // +----------------------------------------------------------------------+ // | This source file is subject to version 2.02 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | // | available at through the world-wide-web at | // | http://www.php.net/license/2_02.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | li...@ph... so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ // | Authors: Peter Bowyer <pe...@ma...> | // +----------------------------------------------------------------------+ // // $Id: IM.php,v 1.1 2004/08/23 17:48:59 joestewart Exp $ // // Image Transformation interface using command line ImageMagick // require_once "Transform.php"; Class Image_Transform_Driver_IM extends Image_Transform { /** * associative array commands to be executed * @var array */ var $command = array(); /** * * */ function Image_Transform_Driver_IM() { return true; } // End Image_IM /** * Load image * * @param string filename * * @return mixed none or a PEAR error object on error * @see PEAR::isError() */ function load($image) { $this->uid = md5($_SERVER['REMOTE_ADDR']); /*if (!file_exists($image)) { return PEAR::raiseError('The image file ' . $image . ' does\'t exist', true); }*/ $this->image = $image; $this->_get_image_details($image); } // End load /** * Resize Action * * @param int new_x new width * @param int new_y new height * * @return none * @see PEAR::isError() */ function _resize($new_x, $new_y) { /*if (isset($this->command['resize'])) { return PEAR::raiseError("You cannot scale or resize an image more than once without calling save or display", true); }*/ $this->command['resize'] = "-geometry ${new_x}x${new_y}!"; $this->new_x = $new_x; $this->new_y = $new_y; } // End resize /** * Crop the image * * @param int $crop_x left column of the image * @param int $crop_y top row of the image * @param int $crop_width new cropped image width * @param int $crop_height new cropped image height */ function crop($crop_x, $crop_y, $crop_width, $crop_height) { $this->command['crop'] = "-crop {$crop_width}x{$crop_height}+{$crop_x}+{$crop_y}"; } /** * Flip the image horizontally or vertically * * @param boolean $horizontal true if horizontal flip, vertical otherwise */ function flip($horizontal) { if($horizontal) $this->command['flop'] = "-flop"; else $this->command['flip'] = "-flip"; } /** * rotate * * @param int angle rotation angle * @param array options no option allowed * */ function rotate($angle, $options=null) { if ('-' == $angle{0}) { $angle = 360 - substr($angle, 1); } $this->command['rotate'] = "-rotate $angle"; } // End rotate /** * addText * * @param array options Array contains options * array( * 'text' The string to draw * 'x' Horizontal position * 'y' Vertical Position * 'Color' Font color * 'font' Font to be used * 'size' Size of the fonts in pixel * 'resize_first' Tell if the image has to be resized * before drawing the text * ) * * @return none * @see PEAR::isError() */ function addText($params) { $default_params = array( 'text' => 'This is Text', 'x' => 10, 'y' => 20, 'color' => 'red', 'font' => 'Arial.ttf', 'resize_first' => false // Carry out the scaling of the image before annotation? ); $params = array_merge($default_params, $params); extract($params); if (true === $resize_first) { // Set the key so that this will be the last item in the array $key = 'ztext'; } else { $key = 'text'; } $this->command[$key] = "-font $font -fill $color -draw 'text $x,$y \"$text\"'"; // Producing error: gs: not found gs: not found convert: Postscript delegate failed [No such file or directory]. } // End addText /** * Adjust the image gamma * * @param float $outputgamma * * @return none */ function gamma($outputgamma=1.0) { $this->command['gamma'] = "-gamma $outputgamma"; } /** * Save the image file * * @param $filename string the name of the file to write to * @param $quality quality image dpi, default=75 * @param $type string (JPG,PNG...) * * @return none */ function save($filename, $type='', $quality = 85) { $type == '' ? $this->type : $type; $cmd = '' . IMAGE_TRANSFORM_LIB_PATH . 'convert '; $cmd .= implode(' ', $this->command) . " -quality $quality "; $cmd .= '"'.($this->image) . '" "' . ($filename) . '" 2>&1'; //$cmd = str_replace('/', '\\', $cmd); //echo($cmd.'<br>'); exec($cmd,$retval); //error_log('IM '.print_r($retval,true)); } // End save /** * Display image without saving and lose changes * * @param string type (JPG,PNG...); * @param int quality 75 * * @return none */ function display($type = '', $quality = 75) { if ($type == '') { header('Content-type: image/' . $this->type); passthru(IMAGE_TRANSFORM_LIB_PATH . 'convert ' . implode(' ', $this->command) . " -quality $quality " . escapeshellarg($this->image) . ' ' . strtoupper($this->type) . ":-"); } else { header('Content-type: image/' . $type); passthru(IMAGE_TRANSFORM_LIB_PATH . 'convert ' . implode(' ', $this->command) . " -quality $quality " . escapeshellarg($this->image) . ' ' . strtoupper($type) . ":-"); } } /** * Destroy image handle * * @return none */ function free() { return true; } } // End class ImageIM ?> --- NEW FILE: ImageEditor.php --- <? /** * Image Editor. Editing tools, crop, rotate, scale and save. * @author $Author: joestewart $ * @version $Id: ImageEditor.php,v 1.1 2004/08/23 17:48:59 joestewart Exp $ * @package ImageManager */ require_once('Transform.php'); /** * Handles the basic image editing capbabilities. * @author $Author: joestewart $ * @version $Id: ImageEditor.php,v 1.1 2004/08/23 17:48:59 joestewart Exp $ * @package ImageManager * @subpackage Editor */ class ImageEditor { /** * ImageManager instance. */ var $manager; /** * user based on IP address */ var $_uid; /** * tmp file storage time. */ var $lapse_time =900; //15 mins var $filesaved = 0; /** * Create a new ImageEditor instance. Editing requires a * tmp file, which is saved in the current directory where the * image is edited. The tmp file is assigned by md5 hash of the * user IP address. This hashed is used as an ID for cleaning up * the tmp files. In addition, any tmp files older than the * the specified period will be deleted. * @param ImageManager $manager the image manager, we need this * for some file and path handling functions. */ function ImageEditor($manager) { $this->manager = $manager; $this->_uid = md5($_SERVER['REMOTE_ADDR']); } /** * Did we save a file? * @return int 1 if the file was saved sucessfully, * 0 no save operation, -1 file save error. */ function isFileSaved() { Return $this->filesaved; } /** * Process the image, if not action, just display the image. * @return array with image information, empty array if not an image. * <code>array('src'=>'url of the image', 'dimensions'=>'width="xx" height="yy"', * 'file'=>'image file, relative', 'fullpath'=>'full path to the image');</code> */ function processImage() { if(isset($_GET['img'])) $relative = rawurldecode($_GET['img']); else Return array(); //$relative = '/Series2004NoteFront.jpg'; $imgURL = $this->manager->getFileURL($relative); $fullpath = $this->manager->getFullPath($relative); $imgInfo = @getImageSize($fullpath); if(!is_array($imgInfo)) Return array(); $action = $this->getAction(); if(!is_null($action)) { $image = $this->processAction($action, $relative, $fullpath); } else { $image['src'] = $imgURL; $image['dimensions'] = $imgInfo[3]; $image['file'] = $relative; $image['fullpath'] = $fullpath; } Return $image; } /** * Process the actions, crop, scale(resize), rotate, flip, and save. * When ever an action is performed, the result is save into a * temporary image file, see createUnique on the filename specs. * It does not return the saved file, alway returning the tmp file. * @param string $action, should be 'crop', 'scale', 'rotate','flip', or 'save' * @param string $relative the relative image filename * @param string $fullpath the fullpath to the image file * @return array with image information * <code>array('src'=>'url of the image', 'dimensions'=>'width="xx" height="yy"', * 'file'=>'image file, relative', 'fullpath'=>'full path to the image');</code> */ function processAction($action, $relative, $fullpath) { $params = ''; if(isset($_GET['params'])) $params = $_GET['params']; $values = explode(',',$params,4); $saveFile = $this->getSaveFileName($values[0]); $img = Image_Transform::factory(IMAGE_CLASS); $img->load($fullpath); switch ($action) { case 'crop': $img->crop(intval($values[0]),intval($values[1]), intval($values[2]),intval($values[3])); break; case 'scale': $img->resize(intval($values[0]),intval($values[1])); break; case 'rotate': $img->rotate(floatval($values[0])); break; case 'flip': if ($values[0] == 'hoz') $img->flip(true); else if($values[0] == 'ver') $img->flip(false); break; case 'save': if(!is_null($saveFile)) { $quality = intval($values[1]); if($quality <0) $quality = 85; $newSaveFile = $this->makeRelative($relative, $saveFile); $newSaveFile = $this->getUniqueFilename($newSaveFile); //get unique filename just returns the filename, so //we need to make the relative path once more. $newSaveFile = $this->makeRelative($relative, $newSaveFile); $newSaveFullpath = $this->manager->getFullPath($newSaveFile); $img->save($newSaveFullpath, $values[0], $quality); if(is_file($newSaveFullpath)) $this->filesaved = 1; else $this->filesaved = -1; } break; } //create the tmp image file $filename = $this->createUnique($fullpath); $newRelative = $this->makeRelative($relative, $filename); $newFullpath = $this->manager->getFullPath($newRelative); $newURL = $this->manager->getFileURL($newRelative); //save the file. $img->save($newFullpath); $img->free(); //get the image information $imgInfo = @getimagesize($newFullpath); $image['src'] = $newURL; $image['dimensions'] = $imgInfo[3]; $image['file'] = $newRelative; $image['fullpath'] = $newFullpath; Return $image; } /** * Get the file name base on the save name * and the save type. * @param string $type image type, 'jpeg', 'png', or 'gif' * @return string the filename according to save type */ function getSaveFileName($type) { if(!isset($_GET['file'])) Return null; $filename = Files::escape(rawurldecode($_GET['file'])); $index = strrpos($filename,'.'); $base = substr($filename,0,$index); $ext = strtolower(substr($filename,$index+1,strlen($filename))); if($type == 'jpeg' && !($ext=='jpeg' || $ext=='jpg')) { Return $base.'.jpeg'; } if($type=='png' && $ext != 'png') Return $base.'.png'; if($type=='gif' && $ext != 'gif') Return $base.'.gif'; Return $filename; } /** * Get the default save file name, used by editor.php. * @return string a suggestive filename, this should be unique */ function getDefaultSaveFile() { if(isset($_GET['img'])) $relative = rawurldecode($_GET['img']); else Return null; Return $this->getUniqueFilename($relative); } /** * Get a unique filename. If the file exists, the filename * base is appended with an increasing integer. * @param string $relative the relative filename to the base_dir * @return string a unique filename in the current path */ function getUniqueFilename($relative) { $fullpath = $this->manager->getFullPath($relative); $pathinfo = pathinfo($fullpath); $path = Files::fixPath($pathinfo['dirname']); $file = Files::escape($pathinfo['basename']); $filename = $file; $dotIndex = strrpos($file, '.'); $ext = ''; if(is_int($dotIndex)) { $ext = substr($file, $dotIndex); $base = substr($file, 0, $dotIndex); } $counter = 0; while(is_file($path.$filename)) { $counter++; $filename = $base.'_'.$counter.$ext; } Return $filename; } /** * Specifiy the original relative path, a new filename * and return the new filename with relative path. * i.e. $pathA (-filename) + $file * @param string $pathA the relative file * @param string $file the new filename * @return string relative path with the new filename */ function makeRelative($pathA, $file) { $index = strrpos($pathA,'/'); if(!is_int($index)) Return $file; $path = substr($pathA, 0, $index); Return Files::fixPath($path).$file; } /** * Get the action GET parameter * @return string action parameter */ function getAction() { $action = null; if(isset($_GET['action'])) $action = $_GET['action']; Return $action; } /** * Generate a unique string based on md5(microtime()). * Well not so uniqe, as it is limited to 6 characters * @return string unique string. */ function uniqueStr() { return substr(md5(microtime()),0,6); } /** * Create unique tmp image file name. * The filename is based on the tmp file prefix * specified in config.inc.php plus * the UID (basically a md5 of the remote IP) * and some random 6 character string. * This function also calls to clean up the tmp files. * @param string $file the fullpath to a file * @return string a unique filename for that path * NOTE: it only returns the filename, path no included. */ function createUnique($file) { $pathinfo = pathinfo($file); $path = Files::fixPath($pathinfo['dirname']); $imgType = $this->getImageType($file); $unique_str = $this->manager->getTmpPrefix().$this->_uid.'_'.$this->uniqueStr().".".$imgType; //make sure the the unique temp file does not exists while (file_exists($path.$unique_str)) { $unique_str = $this->manager->getTmpPrefix().$this->_uid.'_'.$this->uniqueStr().".".$imgType; } $this->cleanUp($path,$pathinfo['basename']); Return $unique_str; } /** * Delete any tmp image files. * @param string $path the full path * where the clean should take place. */ function cleanUp($path,$file) { $path = Files::fixPath($path); if(!is_dir($path)) Return false; $d = @dir($path); $tmp = $this->manager->getTmpPrefix(); $tmpLen = strlen($tmp); $prefix = $tmp.$this->_uid; $len = strlen($prefix); while (false !== ($entry = $d->read())) { //echo $entry."<br>"; if(is_file($path.$entry) && $this->manager->isTmpFile($entry)) { if(substr($entry,0,$len)==$prefix && $entry != $file) Files::delFile($path.$entry); else if(substr($entry,0,$tmpLen)==$tmp && $entry != $file) { if(filemtime($path.$entry)+$this->lapse_time < time()) Files::delFile($path.$entry); } } } $d->close(); } /** * Get the image type base on an image file. * @param string $file the full path to the image file. * @return string of either 'gif', 'jpeg', 'png' or 'bmp' * otherwise it will return null. */ function getImageType($file) { $imageInfo = @getImageSize($file); if(!is_array($imageInfo)) Return null; switch($imageInfo[2]) { case 1: Return 'gif'; case 2: Return 'jpeg'; case 3: Return 'png'; case 6: Return 'bmp'; } Return null; } /** * Check if the specified image can be edit by GD * mainly to check that GD can read and save GIFs * @return int 0 if it is not a GIF file, 1 is GIF is editable, -1 if not editable. */ function isGDEditable() { if(isset($_GET['img'])) $relative = rawurldecode($_GET['img']); else Return 0; if(IMAGE_CLASS != 'GD') Return 0; $fullpath = $this->manager->getFullPath($relative); $type = $this->getImageType($fullpath); if($type != 'gif') Return 0; if(function_exists('ImageCreateFrom'+$type) && function_exists('image'+$type)) Return 1; else Return -1; } /** * Check if GIF can be edit by GD. * @return int 0 if it is not using the GD library, 1 is GIF is editable, -1 if not editable. */ function isGDGIFAble() { if(IMAGE_CLASS != 'GD') Return 0; if(function_exists('ImageCreateFromGif') && function_exists('imagegif')) Return 1; else Return -1; } } ?> --- NEW FILE: ImageManager.php --- <? /** * ImageManager, list images, directories, and thumbnails. * @author $Author: joestewart $ * @version $Id: ImageManager.php,v 1.1 2004/08/23 17:48:59 joestewart Exp $ * @package ImageManager */ require_once('Files.php'); /** * ImageManager Class. * @author $Author: joestewart $ * @version $Id: ImageManager.php,v 1.1 2004/08/23 17:48:59 joestewart Exp $ */ class ImageManager { /** * Configuration array. */ var $config; /** * Array of directory information. */ var $dirs; /** * Constructor. Create a new Image Manager instance. * @param array $config configuration array, see config.inc.php */ function ImageManager($config) { $this->config = $config; } /** * Get the base directory. * @return string base dir, see config.inc.php */ function getBaseDir() { Return $this->config['base_dir']; } /** * Get the base URL. * @return string base url, see config.inc.php */ function getBaseURL() { Return $this->config['base_url']; } function isValidBase() { return is_dir($this->getBaseDir()); } /** * Get the tmp file prefix. * @return string tmp file prefix. */ function getTmpPrefix() { Return $this->config['tmp_prefix']; } /** * Get the sub directories in the base dir. * Each array element contain * the relative path (relative to the base dir) as key and the * full path as value. * @return array of sub directries * <code>array('path name' => 'full directory path', ...)</code> */ function getDirs() { if(is_null($this->dirs)) { $dirs = $this->_dirs($this->getBaseDir(),'/'); ksort($dirs); $this->dirs = $dirs; } return $this->dirs; } /** * Recursively travese the directories to get a list * of accessable directories. * @param string $base the full path to the current directory * @param string $path the relative path name * @return array of accessiable sub-directories * <code>array('path name' => 'full directory path', ...)</code> */ function _dirs($base, $path) { $base = Files::fixPath($base); $dirs = array(); if($this->isValidBase() == false) return $dirs; $d = @dir($base); while (false !== ($entry = $d->read())) { //If it is a directory, and it doesn't start with // a dot, and if is it not the thumbnail directory if(is_dir($base.$entry) && substr($entry,0,1) != '.' && $this->isThumbDir($entry) == false) { $relative = Files::fixPath($path.$entry); $fullpath = Files::fixPath($base.$entry); $dirs[$relative] = $fullpath; $dirs = array_merge($dirs, $this->_dirs($fullpath, $relative)); } } $d->close(); Return $dirs; } /** * Get all the files and directories of a relative path. * @param string $path relative path to be base path. * @return array of file and path information. * <code>array(0=>array('relative'=>'fullpath',...), 1=>array('filename'=>fileinfo array(),...)</code> * fileinfo array: <code>array('url'=>'full url', * 'relative'=>'relative to base', * 'fullpath'=>'full file path', * 'image'=>imageInfo array() false if not image, * 'stat' => filestat)</code> */ function getFiles($path) { $files = array(); $dirs = array(); if($this->isValidBase() == false) return array($files,$dirs); $path = Files::fixPath($path); $base = Files::fixPath($this->getBaseDir()); $fullpath = Files::makePath($base,$path); $d = @dir($fullpath); while (false !== ($entry = $d->read())) { //not a dot file or directory if(substr($entry,0,1) != '.') { if(is_dir($fullpath.$entry) && $this->isThumbDir($entry) == false) { $relative = Files::fixPath($path.$entry); $full = Files::fixPath($fullpath.$entry); $count = $this->countFiles($full); $dirs[$relative] = array('fullpath'=>$full,'entry'=>$entry,'count'=>$count); } else if(is_file($fullpath.$entry) && $this->isThumb($entry)==false && $this->isTmpFile($entry) == false) { $img = $this->getImageInfo($fullpath.$entry); if(!(!is_array($img)&&$this->config['validate_images'])) { $file['url'] = Files::makePath($this->config['base_url'],$path).$entry; $file['relative'] = $path.$entry; $file['fullpath'] = $fullpath.$entry; $file['image'] = $img; $file['stat'] = stat($fullpath.$entry); $files[$entry] = $file; } } } } $d->close(); ksort($dirs); ksort($files); Return array($dirs, $files); } /** * Count the number of files and directories in a given folder * minus the thumbnail folders and thumbnails. */ function countFiles($path) { $total = 0; if(is_dir($path)) { $d = @dir($path); while (false !== ($entry = $d->read())) { //echo $entry."<br>"; if(substr($entry,0,1) != '.' && $this->isThumbDir($entry) == false && $this->isTmpFile($entry) == false && $this->isThumb($entry) == false) { $total++; } } $d->close(); } return $total; } /** * Get image size information. * @param string $file the image file * @return array of getImageSize information, * false if the file is not an image. */ function getImageInfo($file) { Return @getImageSize($file); } /** * Check if the file contains the thumbnail prefix. * @param string $file filename to be checked * @return true if the file contains the thumbnail prefix, false otherwise. */ function isThumb($file) { $len = strlen($this->config['thumbnail_prefix']); if(substr($file,0,$len)==$this->config['thumbnail_prefix']) Return true; else Return false; } /** * Check if the given directory is a thumbnail directory. * @param string $entry directory name * @return true if it is a thumbnail directory, false otherwise */ function isThumbDir($entry) { if($this->config['thumbnail_dir'] == false || strlen(trim($this->config['thumbnail_dir'])) == 0) Return false; else Return ($entry == $this->config['thumbnail_dir']); } /** * Check if the given file is a tmp file. * @param string $file file name * @return boolean true if it is a tmp file, false otherwise */ function isTmpFile($file) { $len = strlen($this->config['tmp_prefix']); if(substr($file,0,$len)==$this->config['tmp_prefix']) Return true; else Return false; } /** * For a given image file, get the respective thumbnail filename * no file existence check is done. * @param string $fullpathfile the full path to the image file * @return string of the thumbnail file */ function getThumbName($fullpathfile) { $path_parts = pathinfo($fullpathfile); $thumbnail = $this->config['thumbnail_prefix'].$path_parts['basename']; if($this->config['safe_mode'] == true || strlen(trim($this->config['thumbnail_dir'])) == 0) { Return Files::makeFile($path_parts['dirname'],$thumbnail); } else { if(strlen(trim($this->config['thumbnail_dir'])) > 0) { $path = Files::makePath($path_parts['dirname'],$this->config['thumbnail_dir']); if(!is_dir($path)) Files::createFolder($path); Return Files::makeFile($path,$thumbnail); } else //should this ever happen? { //error_log('ImageManager: Error in creating thumbnail name'); } } } /** * Similar to getThumbName, but returns the URL, base on the * given base_url in config.inc.php * @param string $relative the relative image file name, * relative to the base_dir path * @return string the url of the thumbnail */ function getThumbURL($relative) { $path_parts = pathinfo($relative); $thumbnail = $this->config['thumbnail_prefix'].$path_parts['basename']; if($path_parts['dirname']=='\\') $path_parts['dirname']='/'; if($this->config['safe_mode'] == true || strlen(trim($this->config['thumbnail_dir'])) == 0) { Return Files::makeFile($this->getBaseURL(),$thumbnail); } else { if(strlen(trim($this->config['thumbnail_dir'])) > 0) { $path = Files::makePath($path_parts['dirname'],$this->config['thumbnail_dir']); $url_path = Files::makePath($this->getBaseURL(), $path); Return Files::makeFile($url_path,$thumbnail); } else //should this ever happen? { //error_log('ImageManager: Error in creating thumbnail url'); } } } /** * Check if the given path is part of the subdirectories * under the base_dir. * @param string $path the relative path to be checked * @return boolean true if the path exists, false otherwise */ function validRelativePath($path) { $dirs = $this->getDirs(); if($path == '/') Return true; //check the path given in the url against the //list of paths in the system. for($i = 0; $i < count($dirs); $i++) { $key = key($dirs); //we found the path if($key == $path) Return true; next($dirs); } Return false; } /** * Process uploaded files, assumes the file is in * $_FILES['upload'] and $_POST['dir'] is set. * The dir must be relative to the base_dir and exists. * If 'validate_images' is set to true, only file with * image dimensions will be accepted. * @return null */ function processUploads() { if($this->isValidBase() == false) return; $relative = null; if(isset($_POST['dir'])) $relative = rawurldecode($_POST['dir']); else return; //check for the file, and must have valid relative path if(isset($_FILES['upload']) && $this->validRelativePath($relative)) { $this->_processFiles($relative, $_FILES['upload']); } } /** * Process upload files. The file must be an * uploaded file. If 'validate_images' is set to * true, only images will be processed. Any duplicate * file will be renamed. See Files::copyFile for details * on renaming. * @param string $relative the relative path where the file * should be copied to. * @param array $file the uploaded file from $_FILES * @return boolean true if the file was processed successfully, * false otherwise */ function _processFiles($relative, $file) { if($file['error']!=0) { Return false; } if(!is_file($file['tmp_name'])) { Return false; } if(!is_uploaded_file($file['tmp_name'])) { Files::delFile($file['tmp_name']); Return false; } if($this->config['validate_images'] == true) { $imgInfo = @getImageSize($file['tmp_name']); if(!is_array($imgInfo)) { Files::delFile($file['tmp_name']); Return false; } } //now copy the file $path = Files::makePath($this->getBaseDir(),$relative); $result = Files::copyFile($file['tmp_name'], $path, $file['name']); //no copy error if(!is_int($result)) { Files::delFile($file['tmp_name']); Return true; } //delete tmp files. Files::delFile($file['tmp_name']); Return false; } /** * Get the URL of the relative file. * basically appends the relative file to the * base_url given in config.inc.php * @param string $relative a file the relative to the base_dir * @return string the URL of the relative file. */ function getFileURL($relative) { Return Files::makeFile($this->getBaseURL(),$relative); } /** * Get the fullpath to a relative file. * @param string $relative the relative file. * @return string the full path, .ie. the base_dir + relative. */ function getFullPath($relative) { Return Files::makeFile($this->getBaseDir(),$relative);; } /** * Get the default thumbnail. * @return string default thumbnail, empty string if * the thumbnail doesn't exist. */ function getDefaultThumb() { if(is_file($this->config['default_thumbnail'])) Return $this->config['default_thumbnail']; else Return ''; } /** * Get the thumbnail url to be displayed. * If the thumbnail exists, and it is up-to-date * the thumbnail url will be returns. If the * file is not an image, a default image will be returned. * If it is an image file, and no thumbnail exists or * the thumbnail is out-of-date (i.e. the thumbnail * modified time is less than the original file) * then a thumbs.php?img=filename.jpg is returned. * The thumbs.php url will generate a new thumbnail * on the fly. If the image is less than the dimensions * of the thumbnails, the image will be display instead. * @param string $relative the relative image file. * @return string the url of the thumbnail, be it * actually thumbnail or a script to generate the * thumbnail on the fly. */ function getThumbnail($relative) { $fullpath = Files::makeFile($this->getBaseDir(),$relative); //not a file??? if(!is_file($fullpath)) Return $this->getDefaultThumb(); $imgInfo = @getImageSize($fullpath); //not an image if(!is_array($imgInfo)) Return $this->getDefaultThumb(); //the original image is smaller than thumbnails, //so just return the url to the original image. if ($imgInfo[0] <= $this->config['thumbnail_width'] && $imgInfo[1] <= $this->config['thumbnail_height']) Return $this->getFileURL($relative); $thumbnail = $this->getThumbName($fullpath); //check for thumbnails, if exists and // it is up-to-date, return the thumbnail url if(is_file($thumbnail)) { if(filemtime($thumbnail) >= filemtime($fullpath)) Return $this->getThumbURL($relative); } //well, no thumbnail was found, so ask the thumbs.php //to generate the thumbnail on the fly. Return 'thumbs.php?img='.rawurlencode($relative); } /** * Delete and specified files. * @return boolean true if delete, false otherwise */ function deleteFiles() { if(isset($_GET['delf'])) $this->_delFile(rawurldecode($_GET['delf'])); } /** * Delete and specified directories. * @return boolean true if delete, false otherwise */ function deleteDirs() { if(isset($_GET['deld'])) return $this->_delDir(rawurldecode($_GET['deld'])); else Return false; } /** * Delete the relative file, and any thumbnails. * @param string $relative the relative file. * @return boolean true if deleted, false otherwise. */ function _delFile($relative) { $fullpath = Files::makeFile($this->getBaseDir(),$relative); //check that the file is an image if($this->config['validate_images'] == true) { if(!is_array($this->getImageInfo($fullpath))) return false; //hmmm not an Image!!??? } $thumbnail = $this->getThumbName($fullpath); if(Files::delFile($fullpath)) Return Files::delFile($thumbnail); else Return false; } /** * Delete directories recursively. * @param string $relative the relative path to be deleted. * @return boolean true if deleted, false otherwise. */ function _delDir($relative) { $fullpath = Files::makePath($this->getBaseDir(),$relative); if($this->countFiles($fullpath) <= 0) return Files::delFolder($fullpath,true); //delete recursively. else Return false; } /** * Create new directories. * If in safe_mode, nothing happens. * @return boolean true if created, false otherwise. */ function processNewDir() { if($this->config['safe_mode'] == true) Return false; if(isset($_GET['newDir']) && isset($_GET['dir'])) { $newDir = rawurldecode($_GET['newDir']); $dir = rawurldecode($_GET['dir']); $path = Files::makePath($this->getBaseDir(),$dir); $fullpath = Files::makePath($path, Files::escape($newDir)); if(is_dir($fullpath)) Return false; Return Files::createFolder($fullpath); } } } ?> --- NEW FILE: NetPBM.php --- <?php /*********************************************************************** ** Title.........: NetPBM Driver ** Version.......: 1.0 ** Author........: Xiang Wei ZHUO <we...@zh...> ** Filename......: NetPBM.php ** Last changed..: 30 Aug 2003 ** Notes.........: Orginal is from PEAR **/ // +----------------------------------------------------------------------+ // | PHP Version 4 | // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2002 The PHP Group | // +----------------------------------------------------------------------+ // | This source file is subject to version 2.02 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | // | available at through the world-wide-web at | // | http://www.php.net/license/2_02.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | li...@ph... so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ // | Authors: Peter Bowyer <pe...@ma...> | // +----------------------------------------------------------------------+ // // $Id: NetPBM.php,v 1.1 2004/08/23 17:48:59 joestewart Exp $ // // Image Transformation interface using command line NetPBM require_once "Transform.php"; Class Image_Transform_Driver_NetPBM extends Image_Transform { /** * associative array commands to be executed * @var array */ var $command = array(); /** * Class Constructor */ function Image_Transform_Driver_NetPBM() { $this->uid = md5($_SERV... [truncated message content] |