* @copyright 2004 by http://wombat.exit0.net * @package wombatSite * @subpackage image */ if( !defined( 'MOGRIFY_BIN' ) ) { /** * mogrify executable, perhaps with path * * don'd ajust this define here - adjust it in any client-specific file (config)! * @link http://www.imagemagick.org */ define( 'MOGRIFY_BIN', 'mogrify' ); } /** * gsImage * * @version 1.1.0 * @package wombatSite * @subpackage image */ class wbImage { var $_rootDir = null; var $_rootWeb = null; var $_baseDir = null; var $_varDir = null; var $_srcDir = 'upload/image'; var $_desDir = 'img/cnt'; var $_webFormats = array( 'image/gif', 'image/jpeg', 'image/png' ); var $_defaultFormat = 'image/jpeg'; /** * different sizes for image tranformation * * @access private * @var array $sizes */ var $_sizes = array(); /** * deffault different sizes for image tranformation * * @access private * @var array $sizes */ var $_sizesDefault = array( '__default' => array( 'width' => 300, 'height' => 300 ), 'thumb' => array( 'width' => 60, 'height' => 60 ), 'web' => array( 'width' => 300, 'height' => 300 ) ); /** * configuration of image sizes loaded from config file * * @access private * @var array $sizes */ var $_sizesConf = array(); /** * dummy image if image does not exist * * @access private * @var string $_noimage file name for dummy image */ var $_noImage = 'noImage.gif'; /** * constructor * * @access public * @param string $dir */ function __construct() { $this->_rootDir = wbFactory::getParam( 'baseDir' );; $this->_rootWeb = wbFactory::getParam( 'htdocDir' ); $this->_varDir = wbFactory::getParam( 'varDir' );; // load default image sizes $conf = wbFactory::singleton( 'patConfiguration' ); $result = $conf->loadConfig( 'images.xml' ); $this->_sizesConf = $conf->getConfigValue( 'sizes' ); if( isset( $this->_sizesConf['__default'] ) ) { $this->_sizesDefault = $this->_sizesConf['__default']; } $this->_sizes = $this->_sizesDefault; } /** * PHP 4 wrapper for constructor * * @access public * @param string $dir */ function wbImage() { $this->__construct(); } /** * change base dir during runtime * * @access private * @param string $dir * @return boolean $result true on success */ function setBaseDir( $dir ) { $this->_baseDir = $dir; if( isset( $this->_sizesConf[$dir] ) ) { $this->_sizes = $this->_sizesConf[$dir]; } else { $this->_sizes = $this->_sizesDefault; wbDebugger::addMsg( 'wbImage', 'No size configuration for dir: "'. $dir.'" found - use default sizes', 'Poor config' ); } return true; } /** * set sizes of for image converting * * @access public * @param array $sizes image sizes for thumbnails, etc * @return boolean $result true on success */ function setSizes( $sizes, $default = true ) { foreach( $sizes as $key => $size ) { // need width and/or height if( $size['width'] == 0 && $size['height'] == 0 ) { return patErrorManager::raiseWarning( 'wbImage:8', 'Wrong image sizes', 'At least width or height must be greater than 0! - given width: "'.$size['width'].'" height: "'.$size['height'].'"!' ); } if( $default ) { $this->_sizesDefault = $size; } $this->_sizes[$key] = $size; } return true; } /** * get information about an image * * This is just a wrapper function to getImageSize. The wrapper includes * selecting image file from the corresponding directory. * * @access private * @param string $type selected image type (a directory name containing images) * @param string $name the filename of the requested image * @return array $image image information * @see getImageSize() */ function getInfo( $name, $type = null ) { $dir = $this->_rootDir . '/' . $this->_rootWeb . '/' . $this->_desDir . '/' . $this->_baseDir; if( $type !== null ) { $dir .= '/' . $type; } if( !is_dir( $dir ) ) { return patErrorManager::raiseWarning( 'wbImage:1', 'Cannot resolve image path.', 'Path: "'.$dir.'" is not a directory.' ); } // use default image if( empty( $name ) ) { $name = $this->_noImage; } if( !file_exists( $dir . '/' . $name ) ) { return patErrorManager::raiseWarning( 'wbImage:2', 'Requested Image does not exist', 'Path: "'.$dir.'" File: "'.$name.'".' ); } $info = @getImageSize( $dir . '/' . $name ); $image = array(); $image['state'] = 'ok'; $image['file'] = $dir . '/' . $name; if( $name === $this->_noImage ) { $image['state'] = 'noimage'; } $image['mime'] = $info['mime']; $image['name'] = $name; $image['width'] = $info[0]; $image['height'] = $info[1]; if( $type !== null ) { $name = $type . '/' . $name; } $image['src'] = $this->_desDir . '/' . $this->_baseDir . '/' . $name; return $image; } /** * remove image for all types * * @access public * @param string $name filename of the image * @return boolean $result true on success */ function erase( $name ) { if( $name == null ) { return false; } $dirs = array_keys( $this->_sizes ); array_push( $dirs, '__upload' ); wbDebugger::addMsg( 'wbImage', 'Types: "' . implode( '", "', $dirs ) . '" image: "'. $name .'"', 'Erase image' ); foreach( $dirs as $dir ) { switch( $dir ) { case '__upload': $src = $this->_rootDir . '/' . $this->_varDir . '/' . $this->_srcDir . '/' . $this->_baseDir; break; case '__default': $src = $this->_rootDir . '/' . $this->_rootWeb . '/' . $this->_desDir . '/' . $this->_baseDir; break; default: $src = $this->_rootDir . '/' . $this->_rootWeb . '/' . $this->_desDir . '/' . $this->_baseDir . '/' . $dir; break; } if( file_exists( $src . '/' . $name ) ) { $result = unlink( $src . '/' . $name ); if( !$result ) { return patErrorManager::raiseError( 'wbImage:erase:1', 'Erase failed', 'Cannot erase image "'. $src . '/' . $name .'"' ); } } } return true; } /** * resizeImage * * @access public * @param string $name filename of the image * @return boolean $result true on success */ function resize( $name ) { $resize = '_resizeImageMogrify'; /*$resize = '_resizeImageGd'; if( file_exists( MOGRIFY_BIN ) ) { $resize = '_resizeImageMogrify'; } */ $result = array(); $src = $this->_rootDir . '/' . $this->_varDir . '/' . $this->_srcDir . '/' . $this->_baseDir; $des = $this->_rootDir . '/' . $this->_rootWeb . '/' . $this->_desDir . '/' . $this->_baseDir; // get some information about original image if( !( $info = @getImageSize( $src . '/' . $name ) ) ) { return patErrorManager::raiseWarning( 'wbImage:3', 'Source image does not exist', 'Path: "'.$src.'" File: "'.$name.'".' ); } // create thumbnail and others foreach( $this->_sizes as $type => $size ) { // calculate scaling factor if( $size['width'] == 0 || $size['height'] == 0 ) { // either height or width must be defined if( $size['width'] > 0 ) { $scale = $size['width'] / $info[0]; } else if( $size['height'] > 0 ) { $scale = $size['height'] / $info[1]; } } else { // calculated scaling factor depending on dimensions of picture $scale = array( $size['width'], $size['height'] ); // landscape if( $info[0] > $info[1] ) { rsort( $scale, SORT_NUMERIC ); } // portrait else { sort( $scale, SORT_NUMERIC ); } // scale factor (keep aspect) $scale = min( $scale[0] / $info[0], $scale[1] / $info[1] ); } $s = array( floor( $info[0] * $scale ), floor( $info[1] * $scale ) ); wbDebugger::addMsg( 'wbImage', 'Type: "' . $type . '" image: "'. $name .'" to: '.$s[0].'x'.$s[1].'.', 'Resize image' ); if( $type === '__default' ) { $type = '.'; } $res = $this->$resize( $src . '/' . $name, $des . '/' . $type . '/' . $name, $s[0], $s[1] ); if( patErrorManager::isError( $res ) ) { return $result; } } return $result; } /** * create destination directory * * * @access private * @param string $des name of destination directory * @return boolean $result true on success */ function _createDestination( $des ) { $des = str_replace( '\\', '/', $des ); $path = explode( '/', $des ); array_pop( $path ); $current = array(); foreach( $path as $dir ) { array_push( $current, $dir ); $curPath = implode( '/', $current ); if( empty( $curPath ) ) { continue; } if( !is_dir( $curPath ) ) { // create dir which is writable for everyone if( !mkdir( $curPath, 0777 ) ) { return patErrorManager::raiseError( 'wbImage:4', 'Cant\'t create destination directory.', 'Makedir of "'. $curPath .'" failed' ); } } } return true; } /** * resize image using mogrify * {@link http://www.imagemagick.org} * * @access private * * @return boolean $result true on success */ function _resizeImageMogrify( $src, $des, $x, $y ) { $src = realpath( $src ); $res = $this->_createDestination( $des ); if( patErrorManager::isError( $des ) ) { return $res; } // copy image if( !copy( $src, $des ) ) { return patErrorManager::raiseWarning( 'wbImage:5', 'Cant\'t copy image file.', 'Copy form '. $src .' to '. $des .' failed' ); } // call mogrify $exec = MOGRIFY_BIN . ' -resize '.$x.'x'.$y.'! '. $des; exec( $exec, $output, $retVal ); if( $retVal ) { return patErrorManager::raiseWarning( 'wbImage:6', 'Cant\'t resize Image by use Mogrify', 'Imagefile:'. $src .'!' ); } /* * workaround for different versiond of ImageMagick * * Some version of mogrify don't overwrite the source image while resizing. * In this case mogrify stores the output image in a seperated file named .mgk */ $info = pathinfo( $des ); $info['base'] = basename( $info['basename'], '.' . $info['extension'] ); // check if mogrify .mgk file exits $mgk = $info['dirname'] . '/' . $info['base'] . '.mgk'; if( file_exists( $mgk ) ) { rename( $mgk, $des ); } if( !is_file( $des ) ) { return false; } // finally make file accessable for everyone chmod( $des, 0666 ); return true; } /** * resizeImageGd * * @access private * @return boolean $result true on success */ function _resizeImageGd( $src, $des, $x, $y ) { $res = $this->_createDestination( $des ); if( patErrorManager::isError( $des ) ) { return $res; } $info = @getImageSize( $src ); $org = false; switch( $info[2] ) { // "image/jpeg": case 2: $org = @imageCreateFromJPEG( $src ); break; // "image/png": case 3: $org = @imageCreateFromPNG( $src ); break; // "image/gif": case 1: $org = @imageCreateFromGif( $src ); break; } if( !$org ) { return patErrorManager::raiseWarning( 'wbImage:7', 'Invalid image resource', 'Imagefile:'. $src .'!' ); } $resize = imagecreate( $x, $y ); imageCopyResized( $resize, $org, 0, 0, 0, 0, $x, $y, $info[0], $info[1] ); switch( $info[2] ) { // "image/jpeg": case 2: imagejpeg( $resize, $des ); break; // "image/png": case 3: imagepng( $resize, $des ); break; // "image/gif": case 1: imagegif( $resize, $des ); break; } imageDestroy( $resize ); imageDestroy( $org ); // finally make file accessable for everyone chmod( $des, 0666 ); return true; } } ?>