|
eZ Publish
[trunk]
|
00001 <?php 00002 /** 00003 * File containing the eZImageGDHandler class. 00004 * 00005 * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved. 00006 * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2 00007 * @version //autogentag// 00008 * @package lib 00009 */ 00010 00011 /*! 00012 \class eZImageGDHandler ezimagegdhandler.php 00013 \ingroup eZImage 00014 \brief The class eZImageGDHandler does 00015 00016 A geometry array has the following entries. 00017 - x - The x position 00018 - y - The y position 00019 - width - The width 00020 - height - The height 00021 */ 00022 00023 class eZImageGDHandler extends eZImageHandler 00024 { 00025 /*! 00026 Constructor 00027 */ 00028 function eZImageGDHandler( $handlerName, $isGloballyEnabled, 00029 $outputRewriteType = self::REPLACE_SUFFIX, 00030 $conversionRules = false ) 00031 { 00032 $supportedInputMIMETypes = array(); 00033 $supportedOutputMIMETypes = array(); 00034 $this->InputMap = array(); 00035 $this->OutputMap = array(); 00036 $this->OutputQualityMap = array(); 00037 $isEnabled = false; 00038 if ( function_exists( "imagetypes" ) ) 00039 { 00040 $gdFunctions = array( array( 'mimetype' => 'image/gif', 00041 'input' => 'imagecreatefromgif', 00042 'output' => 'imagegif' ), 00043 array( 'mimetype' => 'image/vnd.wap.wbmp', 00044 'input' => 'imagecreatefromwbmp', 00045 'output' => 'imagewbmp' ), 00046 array( 'mimetype' => 'image/png', 00047 'input' => 'imagecreatefrompng', 00048 'output' => 'imagepng' ), 00049 array( 'mimetype' => 'image/jpeg', 00050 'input' => 'imagecreatefromjpeg', 00051 'output' => 'imagejpeg', 00052 'qualityparameter' => true ) ); 00053 foreach ( $gdFunctions as $gdFunction ) 00054 { 00055 $inputFunction = $gdFunction['input']; 00056 $outputFunction = $gdFunction['output']; 00057 if ( function_exists( $inputFunction ) or function_exists( $outputFunction ) ) 00058 { 00059 $isEnabled = true; 00060 $mimeType = $gdFunction['mimetype']; 00061 if ( function_exists( $inputFunction ) ) 00062 { 00063 $supportedInputMIMETypes[] = $mimeType; 00064 $this->InputMap[$mimeType] = $inputFunction; 00065 } 00066 if ( function_exists( $outputFunction ) ) 00067 { 00068 $this->OutputMap[$mimeType] = $outputFunction; 00069 $supportedOutputMIMETypes[] = $mimeType; 00070 } 00071 if ( isset( $gdFunction['qualityparameter'] ) ) 00072 $this->OutputQualityMap[$mimeType] = $gdFunction['qualityparameter']; 00073 else 00074 $this->OutputQualityMap[$mimeType] = false; 00075 } 00076 } 00077 } 00078 if ( !$isGloballyEnabled ) 00079 $isEnabled = false; 00080 $this->FilterFunctionMap = array( 'geometry/scale' => 'scaleImage', 00081 'geometry/scalewidth' => 'scaleImageWidth', 00082 'geometry/scaleheight' => 'scaleImageHeight', 00083 'geometry/scaledownonly' => 'scaleImageDownOnly', 00084 'geometry/scalewidthdownonly' => 'scaleImageWidthDownOnly', 00085 'geometry/scaleheightdownonly' => 'scaleImageHeightDownOnly', 00086 'geometry/scaleexact' => 'scaleImageExact', 00087 'geometry/scalepercent' => 'scaleImagePercent', 00088 'geometry/crop' => 'cropImage', 00089 'colorspace/gray' => 'setImageColorspaceGray', 00090 'luminance' => 'setImageLuminance', 00091 'luminance/gray' => 'setImageLuminanceNamed', 00092 'luminance/sepia' => 'setImageLuminanceNamed', 00093 'color/monochrome' => 'setImageColorThresholdName', 00094 'border' => 'createImageBorder', 00095 'border/color' => 'setImageBorderColor', 00096 'border/width' => 'setImageBorderWidth' ); 00097 $this->LuminanceColorScales = array( 'luminance/gray' => array( 1.0, 1.0, 1.0 ), 00098 'luminance/sepia' => array( 1.0, 0.89, 0.74 ) ); 00099 $this->ThresholdList = array( 'color/monochrome' => array( array( 'threshold' => 127, 00100 'rgb' => array( 0, 0, 0 ) ), 00101 array( 'threshold' => 255, 00102 'rgb' => array( 255, 255, 255 ) ) ) ); 00103 00104 $filters = array(); 00105 foreach ( $this->FilterFunctionMap as $filterName => $filterFunction ) 00106 { 00107 $filters[] = array( 'name' => $filterName ); 00108 } 00109 $this->eZImageHandler( $handlerName, $isEnabled, 00110 $outputRewriteType, 00111 $supportedInputMIMETypes, $supportedOutputMIMETypes, 00112 $conversionRules, $filters ); 00113 } 00114 00115 /*! 00116 Creates the shell string and runs the executable. 00117 */ 00118 function convert( $manager, $sourceMimeData, &$destinationMimeData, $filters = false ) 00119 { 00120 $sourceMimeType = $sourceMimeData['name']; 00121 $destinationMimeType = $destinationMimeData['name']; 00122 if ( !isset( $this->InputMap[$sourceMimeType] ) ) 00123 { 00124 eZDebug::writeError( "MIME-Type $sourceMimeType is not supported as input by GD converter", __METHOD__ ); 00125 return false; 00126 } 00127 if ( !isset( $this->OutputMap[$destinationMimeType] ) ) 00128 { 00129 eZDebug::writeError( "MIME-Type $destinationMimeType is not supported as output by GD converter", __METHOD__ ); 00130 return false; 00131 } 00132 00133 $inputFunction = $this->InputMap[$sourceMimeType]; 00134 $outputFunction = $this->OutputMap[$destinationMimeType]; 00135 $outputQualityParameter = $this->OutputQualityMap[$destinationMimeType]; 00136 $inputFile = $sourceMimeData['url']; 00137 $outputFile = $destinationMimeData['url']; 00138 00139 if ( !file_exists( $inputFile ) ) 00140 { 00141 eZDebug::writeError( "Source image $inputFile does not exist, cannot convert", __METHOD__ ); 00142 return false; 00143 } 00144 00145 $currentImage = $inputFunction( $inputFile ); 00146 00147 $filterVariables = array( 'border-color' => array( 127, 127, 127 ), 00148 'border-size' => array( 0, 0 ) ); 00149 00150 if ( $filters !== false ) 00151 { 00152 foreach ( $filters as $filterData ) 00153 { 00154 $filterName = $filterData['name']; 00155 if ( isset( $this->FilterFunctionMap[$filterName] ) ) 00156 { 00157 $filterFunction = $this->FilterFunctionMap[$filterName]; 00158 $filteredImage = $this->$filterFunction( $currentImage, $filterData, $filterVariables, $sourceMimeData, $destinationMimeData ); 00159 if ( $filteredImage !== false ) 00160 { 00161 if ( $filteredImage != $currentImage ) 00162 { 00163 ImageDestroy( $currentImage ); 00164 } 00165 $currentImage = $filteredImage; 00166 } 00167 } 00168 } 00169 } 00170 00171 $outputImage = $currentImage; 00172 00173 if ( $outputImage ) 00174 { 00175 $outputQuality = false; 00176 if ( $outputQualityParameter ) 00177 $outputQuality = $manager->qualityValue( $destinationMimeType ); 00178 if ( $outputQuality !== false ) 00179 { 00180 $returnCode = $outputFunction( $outputImage, $outputFile, $outputQuality ); 00181 } 00182 else 00183 { 00184 $returnCode = $outputFunction( $outputImage, $outputFile ); 00185 } 00186 00187 ImageDestroy( $outputImage ); 00188 } 00189 else 00190 $returnCode = false; 00191 00192 if ( $returnCode ) 00193 { 00194 if ( !file_exists( $destinationMimeData['url'] ) ) 00195 { 00196 eZDebug::writeError( "Unknown destination file: " . $destinationMimeData['url'], "eZImageGDHandler(" . $this->HandlerName . ")" ); 00197 return false; 00198 } 00199 $this->changeFilePermissions( $destinationMimeData['url'] ); 00200 return true; 00201 } 00202 else 00203 { 00204 eZDebug::writeWarning( "Failed converting $inputFile ($sourceMimeType) to $outputFile ($destinationMimeType)", __METHOD__ ); 00205 return false; 00206 } 00207 } 00208 00209 static function setImageBorderColor( &$imageObject, $filterData, &$filterVariables, $sourceMimeData, $destinationMimeData ) 00210 { 00211 $filterVariables['border-color'] = $filterData['data']; 00212 return false; 00213 } 00214 00215 function setImageBorderWidth( $imageObject, $filterData, &$filterVariables, $sourceMimeData, $destinationMimeData ) 00216 { 00217 $filterVariables['border-size'] = array( $filterData['data'][0], $filterData['data'][0] ); 00218 return $this->createImageBorder( $imageObject, $filterData, $filterVariables, $sourceMimeData, $destinationMimeData ); 00219 } 00220 00221 function setImageBorder( $imageObject, $filterData, &$filterVariables, $sourceMimeData, $destinationMimeData ) 00222 { 00223 $filterVariables['border-size'] = array( $filterData['data'][0], $filterData['data'][1] ); 00224 return $this->createImageBorder( $imageObject, $filterData, $filterVariables, $sourceMimeData, $destinationMimeData ); 00225 } 00226 00227 function createImageBorder( $imageObject, $filterData, &$filterVariables, $sourceMimeData, $destinationMimeData ) 00228 { 00229 $width = ImageSX( $imageObject ); 00230 $height = ImageSY( $imageObject ); 00231 $borderWidth = $filterVariables['border-size'][0]; 00232 $borderHeight = $filterVariables['border-size'][1]; 00233 $borderColor = $filterVariables['border-color']; 00234 $newWidth = $width + $borderWidth*2; 00235 $newHeight = $height + $borderHeight*2; 00236 00237 $temporaryImageObject = $this->imageCopy( $imageObject, 00238 $this->createGeometry( $newWidth, $newHeight, $borderWidth, $borderHeight ), 00239 $this->createGeometry( $width, $height, 0, 0 ), 00240 $sourceMimeData, $destinationMimeData ); 00241 $color = ImageColorAllocate( $temporaryImageObject, $borderColor[0], $borderColor[1], $borderColor[2] ); 00242 ImageFilledRectangle( $temporaryImageObject, 0, 0, $newWidth, $borderHeight, $color ); 00243 ImageFilledRectangle( $temporaryImageObject, $newWidth - $borderWidth, 0, $newWidth, $newHeight, $color ); 00244 ImageFilledRectangle( $temporaryImageObject, 0, $newHeight - $borderHeight, $newWidth, $newHeight, $color ); 00245 ImageFilledRectangle( $temporaryImageObject, 0, 0, $borderWidth, $newHeight, $color ); 00246 return $temporaryImageObject; 00247 } 00248 00249 /*! 00250 Converts the image to grayscale. 00251 */ 00252 function setImageColorspaceGray( $imageObject, $filterData, &$filterVariables, $sourceMimeData, $destinationMimeData ) 00253 { 00254 $colorScale = array( 1.0, 1.0, 1.0 ); 00255 return $this->setImageLuminanceColorScale( $imageObject, $filterData, $sourceMimeData, $destinationMimeData, 00256 $colorScale ); 00257 } 00258 00259 /*! 00260 Changes the colors of the image based on the luminance. 00261 The new scale for the colors are taken from the filter parameters, the parameters must contain three values. 00262 */ 00263 function setImageLuminance( $imageObject, $filterData, &$filterVariables, $sourceMimeData, $destinationMimeData ) 00264 { 00265 $colorScale = $filterData['data']; 00266 return $this->setImageLuminanceColorScale( $imageObject, $filterData, $sourceMimeData, $destinationMimeData, 00267 $colorScale ); 00268 } 00269 00270 /*! 00271 Changes the colors of the image based on the luminance. 00272 The new scale for the colors are based on the name of the filters. 00273 */ 00274 function setImageLuminanceNamed( $imageObject, $filterData, &$filterVariables, $sourceMimeData, $destinationMimeData ) 00275 { 00276 if ( isset( $this->LuminanceColorScales[$filterData['name']] ) ) 00277 { 00278 $colorScale = $this->LuminanceColorScales[$filterData['name']]; 00279 } 00280 else 00281 { 00282 eZDebug::writeDebug( "No luminance scale named " . $filterData['name'] . ", applying gray scales", __METHOD__ ); 00283 $colorScale = array( 1.0, 1.0, 1.0 ); 00284 } 00285 return $this->setImageLuminanceColorScale( $imageObject, $filterData, $sourceMimeData, $destinationMimeData, 00286 $colorScale ); 00287 } 00288 00289 /*! 00290 Changes the colors of the image based on the luminance. 00291 \param $colorScale is an array with three float elements in range 0 to 1 that define the new color scale. 00292 */ 00293 function setImageLuminanceColorScale( $imageObject, $filterData, $sourceMimeData, $destinationMimeData, 00294 $colorScale ) 00295 { 00296 $white = ImageColorAllocate( $imageObject, 255, 255, 255 ); 00297 $black = ImageColorAllocate( $imageObject, 0, 0, 0 ); 00298 00299 $rmod = $colorScale[0]; 00300 $gmod = $colorScale[1]; 00301 $bmod = $colorScale[2]; 00302 00303 $width = ImageSX( $imageObject ); 00304 $height = ImageSY( $imageObject ); 00305 for ( $y = 0; $y < $height; ++$y ) 00306 { 00307 for ( $x = 0; $x < $width; ++$x ) 00308 { 00309 $rgb = ImageColorAt( $imageObject, $x, $y ); 00310 00311 $r = ( $rgb >> 16 ) & 0xff; 00312 $g = ( $rgb >> 8 ) & 0x0ff; 00313 $b = ( $rgb ) & 0x0ff; 00314 00315 $luminance = ( $r * 0.3 ) + ( $g * 0.59 ) + ( $b * 0.11 ); 00316 00317 $r = $luminance * $rmod; 00318 $g = $luminance * $gmod; 00319 $b = $luminance * $bmod; 00320 00321 $color = ImageColorAllocate( $imageObject, $r, $g, $b ); 00322 00323 ImageSetPixel( $imageObject, $x, $y, $color ); 00324 } 00325 } 00326 return $imageObject; 00327 } 00328 00329 /*! 00330 Changes the colors of the image based on threshold values. 00331 The threshold values are based on the filter name. 00332 */ 00333 function setImageColorThresholdName( $imageObject, $filterData, &$filterVariables, $sourceMimeData, $destinationMimeData ) 00334 { 00335 if ( isset( $this->ThresholdList[$filterData['name']] ) ) 00336 { 00337 $thresholdList = $this->ThresholdList[$filterData['name']]; 00338 } 00339 else 00340 { 00341 eZDebug::writeDebug( "No threshold values named " . $filterData['name'] . ", applying black/white (monochrome) threshold", __METHOD__ ); 00342 $thresholdList = array( array( 'threshold' => 127, 00343 'rgb' => array( 0, 0, 0 ) ), 00344 array( 'threshold' => 255, 00345 'rgb' => array( 255, 255, 255 ) ) ); 00346 } 00347 return $this->setImageColorThreshold( $imageObject, $filterData, $sourceMimeData, $destinationMimeData, 00348 $thresholdList ); 00349 } 00350 00351 /*! 00352 Changes the colors of the image based on threshold values. The luminance will be calculated and if it is 00353 in a threshold range it will use the specified color for the range. 00354 */ 00355 static function setImageColorThreshold( $imageObject, $filterData, $sourceMimeData, $destinationMimeData, 00356 $thresholdList ) 00357 { 00358 foreach ( array_keys( $thresholdList ) as $thresholdKey ) 00359 { 00360 $thresholdList[$thresholdKey]['color'] = ImageColorAllocate( $imageObject, $thresholdItem['rgb'][0], $thresholdItem['rgb'][1], $thresholdItem['rgb'][2] ); 00361 } 00362 $defaultColor = $thresholdList[count( $thresholdList ) - 1]['color']; 00363 00364 $width = ImageSX( $imageObject ); 00365 $height = ImageSY( $imageObject ); 00366 for ( $y = 0; $y < $height; ++$y ) 00367 { 00368 for ( $x = 0; $x < $width; ++$x ) 00369 { 00370 $rgb = ImageColorAt( $imageObject, $x, $y ); 00371 00372 $r = ( $rgb >> 16 ) & 0xff; 00373 $g = ( $rgb >> 8 ) & 0x0ff; 00374 $b = ( $rgb ) & 0x0ff; 00375 00376 $luminance = ( $r * 0.3 ) + ( $g * 0.59 ) + ( $b * 0.11 ); 00377 00378 $color = false; 00379 foreach ( $thresholdList as $thresholdItem ) 00380 { 00381 if ( $luminance <= $thresholdItem['threshold'] ) 00382 { 00383 $color = $thresholdItem['color']; 00384 break; 00385 } 00386 } 00387 if ( $color === false ) 00388 $color = $defaultColor; 00389 00390 ImageSetPixel( $imageObject, $x, $y, $color ); 00391 } 00392 } 00393 return $imageObject; 00394 } 00395 00396 /*! 00397 Crops a portion of the image from the filter parameters. 00398 */ 00399 function cropImage( $imageObject, $filterData, &$filterVariables, $sourceMimeData, $destinationMimeData ) 00400 { 00401 $width = $filterData['data'][0]; 00402 $height = $filterData['data'][1]; 00403 $x = $filterData['data'][2]; 00404 $y = $filterData['data'][3]; 00405 $imageWidth = ImageSX( $imageObject ); 00406 $imageHeight = ImageSY( $imageObject ); 00407 $width = max( min( $width, $imageWidth - $x ), 0 ); 00408 $height = max( min( $height, $imageHeight - $y ), 0 ); 00409 $destinationGeometry = $this->createGeometry( $width, $height, 0, 0 ); 00410 $geometry = $this->createGeometry( $width, $height, $x, $y ); 00411 return $this->imageCopy( $imageObject, 00412 $destinationGeometry, 00413 $geometry, 00414 $sourceMimeData, $destinationMimeData ); 00415 } 00416 00417 /*! 00418 Scales the image \a $imageObject to the size specified in \a $filterData with aspect ration maintained. 00419 This means that image will not be exactly the image size. 00420 \sa scaleImageExact 00421 */ 00422 function scaleImage( $imageObject, $filterData, &$filterVariables, $sourceMimeData, $destinationMimeData ) 00423 { 00424 $geometry = $this->calculateScaledAspectGeometry( ImageSX( $imageObject ), ImageSY( $imageObject ), 00425 $filterData['data'][0], $filterData['data'][1], true ); 00426 return $this->scaleImageCopy( $imageObject, 00427 $geometry, 00428 $sourceMimeData, $destinationMimeData ); 00429 } 00430 00431 /*! 00432 Scales the image \a $imageObject to the size specified in \a $filterData with aspect ration maintained. 00433 This means that image will not be exactly the image size. 00434 \note The image will not be scaled if the source size is smaller than the destination size. 00435 \sa scaleImageExact 00436 */ 00437 function scaleImageDownOnly( $imageObject, $filterData, &$filterVariables, $sourceMimeData, $destinationMimeData ) 00438 { 00439 $geometry = $this->calculateScaledAspectGeometry( ImageSX( $imageObject ), ImageSY( $imageObject ), 00440 $filterData['data'][0], $filterData['data'][1], false ); 00441 return $this->scaleImageCopy( $imageObject, 00442 $geometry, 00443 $sourceMimeData, $destinationMimeData ); 00444 } 00445 00446 /*! 00447 Scales the image \a $imageObject to the size specified in \a $filterData with aspect ration maintained. 00448 This means that image will not be exactly the image size. 00449 \sa scaleImageExact 00450 */ 00451 function scaleImageWidth( $imageObject, $filterData, &$filterVariables, $sourceMimeData, $destinationMimeData ) 00452 { 00453 $geometry = $this->calculateFixedWidthAspectGeometry( ImageSX( $imageObject ), ImageSY( $imageObject ), 00454 $filterData['data'][0], true ); 00455 return $this->scaleImageCopy( $imageObject, 00456 $geometry, 00457 $sourceMimeData, $destinationMimeData ); 00458 } 00459 00460 /*! 00461 Scales the image \a $imageObject to the size specified in \a $filterData with aspect ration maintained. 00462 This means that image will not be exactly the image size. 00463 \sa scaleImageExact 00464 */ 00465 function scaleImageHeight( $imageObject, $filterData, &$filterVariables, $sourceMimeData, $destinationMimeData ) 00466 { 00467 $geometry = $this->calculateFixedHeightAspectGeometry( ImageSX( $imageObject ), ImageSY( $imageObject ), 00468 $filterData['data'][0], true ); 00469 return $this->scaleImageCopy( $imageObject, 00470 $geometry, 00471 $sourceMimeData, $destinationMimeData ); 00472 } 00473 00474 /*! 00475 Scales the image \a $imageObject to the size specified in \a $filterData with aspect ration maintained. 00476 This means that image will not be exactly the image size. 00477 \note The image will not be scaled if the source size is smaller than the destination size. 00478 \sa scaleImageExact 00479 */ 00480 function scaleImageWidthDownOnly( $imageObject, $filterData, &$filterVariables, $sourceMimeData, $destinationMimeData ) 00481 { 00482 $geometry = $this->calculateFixedWidthAspectGeometry( ImageSX( $imageObject ), ImageSY( $imageObject ), 00483 $filterData['data'][0], false ); 00484 return $this->scaleImageCopy( $imageObject, 00485 $geometry, 00486 $sourceMimeData, $destinationMimeData ); 00487 } 00488 00489 /*! 00490 Scales the image \a $imageObject to the size specified in \a $filterData with aspect ration maintained. 00491 This means that image will not be exactly the image size. 00492 \note The image will not be scaled if the source size is smaller than the destination size. 00493 \sa scaleImageExact 00494 */ 00495 function scaleImageHeightDownOnly( $imageObject, $filterData, &$filterVariables, $sourceMimeData, $destinationMimeData ) 00496 { 00497 $geometry = $this->calculateFixedHeightAspectGeometry( ImageSX( $imageObject ), ImageSY( $imageObject ), 00498 $filterData['data'][0], false ); 00499 return $this->scaleImageCopy( $imageObject, 00500 $geometry, 00501 $sourceMimeData, $destinationMimeData ); 00502 } 00503 00504 /*! 00505 Scales the image \a $imageObject to the size specified in \a $filterData without caring about aspect ratio. 00506 */ 00507 function scaleImageExact( $imageObject, $filterData, &$filterVariables, $sourceMimeData, $destinationMimeData ) 00508 { 00509 return $this->scaleImageCopy( $imageObject, 00510 $this->createGeometry( $filterData['data'][0], $filterData['data'][1] ), 00511 $sourceMimeData, $destinationMimeData ); 00512 } 00513 00514 /*! 00515 Scales the image \a $imageObject to the size specified in \a $filterData with aspect ratio maintained. 00516 */ 00517 function scaleImagePercent( $imageObject, $filterData, &$filterVariables, $sourceMimeData, $destinationMimeData ) 00518 { 00519 $geometry = $this->calculateScaledPercentAspectGeometry( ImageSX( $imageObject ), ImageSY( $imageObject ), 00520 $filterData['data'][0] / 100.0, $filterData['data'][1] / 100.0, true ); 00521 return $this->scaleImageCopy( $imageObject, 00522 $geometry, 00523 $sourceMimeData, $destinationMimeData ); 00524 } 00525 00526 /*! 00527 Calculates the geometry for the scaled image while maintaining the aspect ratio. 00528 \param $allowUpScale If this is true images will be scaled up as well, if not they will keep their source size. 00529 \return a geometry array. 00530 \sa createGeometry 00531 */ 00532 function calculateScaledAspectGeometry( $sourceWidth, $sourceHeight, 00533 $destinationWidth, $destinationHeight, 00534 $allowUpScale ) 00535 { 00536 $widthScale = $sourceWidth / $destinationWidth; 00537 $heightScale = $sourceHeight / $destinationHeight; 00538 00539 $scale = $heightScale; 00540 if ( $heightScale != $widthScale ) 00541 $scale = max( $heightScale, $widthScale ); 00542 00543 if ( $scale < 1.0 and !$allowUpScale ) 00544 { 00545 $destinationWidth = $sourceWidth; 00546 $destinationHeight = $sourceHeight; 00547 } 00548 else 00549 { 00550 $destinationWidth = (int) ( $sourceWidth / $scale ); 00551 $destinationHeight = (int) ( $sourceHeight / $scale ); 00552 } 00553 return $this->createGeometry( $destinationWidth, $destinationHeight ); 00554 } 00555 00556 /*! 00557 Calculates the geometry for the scaled image in terms of percent while maintaining the aspect ratio. 00558 \param $allowUpScale If this is true images will be scaled up as well, if not they will keep their source size. 00559 \note Percentage must be given as a float value, e.g. 50% is 0.5 and 200% is 2.0 00560 \return a geometry array. 00561 \sa createGeometry 00562 */ 00563 function calculateScaledPercentAspectGeometry( $sourceWidth, $sourceHeight, 00564 $destinationWidthPercent, $destinationHeightPercent, 00565 $allowUpScale ) 00566 { 00567 $destinationWidth = $sourceWidth * $destinationWidthPercent; 00568 $destinationHeight = $sourceHeight * $destinationHeightPercent; 00569 return $this->calculateScaledAspectGeometry( $sourceWidth, $sourceHeight, 00570 $destinationWidth, $destinationHeight, 00571 $allowUpScale ); 00572 } 00573 00574 /*! 00575 Calculates the geometry for the scaled image with a fixed width while maintaining the aspect ratio. 00576 \param $allowUpScale If this is true images will be scaled up as well, if not they will keep their source size. 00577 \return a geometry array. 00578 \sa createGeometry 00579 */ 00580 function calculateFixedWidthAspectGeometry( $sourceWidth, $sourceHeight, 00581 $destinationWidth, 00582 $allowUpScale ) 00583 { 00584 $scale = $sourceWidth / $destinationWidth; 00585 00586 if ( $scale < 1.0 and !$allowUpScale ) 00587 { 00588 $destinationWidth = $sourceWidth; 00589 $destinationHeight = $sourceHeight; 00590 } 00591 else 00592 { 00593 $destinationWidth = (int) ( $sourceWidth / $scale ); 00594 $destinationHeight = (int) ( $sourceHeight / $scale ); 00595 } 00596 return $this->createGeometry( $destinationWidth, $destinationHeight ); 00597 } 00598 00599 /*! 00600 Calculates the geometry for the scaled image with a fixed height while maintaining the aspect ratio. 00601 \param $allowUpScale If this is true images will be scaled up as well, if not they will keep their source size. 00602 \return a geometry array. 00603 \sa createGeometry 00604 */ 00605 function calculateFixedHeightAspectGeometry( $sourceWidth, $sourceHeight, 00606 $destinationHeight, 00607 $allowUpScale ) 00608 { 00609 $scale = $sourceHeight / $destinationHeight; 00610 00611 if ( $scale < 1.0 and !$allowUpScale ) 00612 { 00613 $destinationWidth = $sourceWidth; 00614 $destinationHeight = $sourceHeight; 00615 } 00616 else 00617 { 00618 $destinationWidth = (int) ( $sourceWidth / $scale ); 00619 $destinationHeight = (int) ( $sourceHeight / $scale ); 00620 } 00621 return $this->createGeometry( $destinationWidth, $destinationHeight ); 00622 } 00623 00624 /*! 00625 Scales the image \a $imageObject to the size specified in \a $filterData. 00626 */ 00627 static function scaleImageCopy( $imageObject, 00628 $geometry, 00629 $sourceMimeData, $destinationMimeData ) 00630 { 00631 $destinationWidth = $geometry['width']; 00632 $destinationHeight = $geometry['height']; 00633 $sourceWidth = ImageSX( $imageObject ); 00634 $sourceHeight = ImageSY( $imageObject ); 00635 00636 $temporaryImageObject = eZImageGDHandler::imageCreate( $destinationWidth, $destinationHeight, eZImageGDHandler::isImageTrueColor( $imageObject, $sourceMimeData ) ); 00637 imagealphablending( $temporaryImageObject, false ); 00638 imagesavealpha( $temporaryImageObject, true ); 00639 ImageCopyResampled( $temporaryImageObject, $imageObject, 00640 0, 0, 0, 0, 00641 $destinationWidth, $destinationHeight, $sourceWidth, $sourceHeight ); 00642 return $temporaryImageObject; 00643 } 00644 00645 /*! 00646 Copies a portion of the source image \a $imageObject to a new image. 00647 */ 00648 static function imageCopy( $imageObject, $destinationGeometry, $sourceGeometry, 00649 $sourceMimeData, $destinationMimeData ) 00650 { 00651 $destinationWidth = $destinationGeometry['width']; 00652 $destinationHeight = $destinationGeometry['height']; 00653 00654 $temporaryImageObject = eZImageGDHandler::imageCreate( $destinationWidth, $destinationHeight, eZImageGDHandler::isImageTrueColor( $imageObject, $sourceMimeData ) ); 00655 ImageCopy( $temporaryImageObject, $imageObject, 00656 $destinationGeometry['x'], $destinationGeometry['y'], 00657 $sourceGeometry['x'], $sourceGeometry['y'], $sourceGeometry['width'], $sourceGeometry['height'] ); 00658 return $temporaryImageObject; 00659 } 00660 00661 /*! 00662 \static 00663 \return \c true if the image object \a $imageObject is in true color format. 00664 */ 00665 static function isImageTrueColor( &$imageObject, $mimeData ) 00666 { 00667 return ImageIsTrueColor( $imageObject ); 00668 } 00669 00670 /*! 00671 Creates a new GD image and returns it. 00672 \param $isTrueColor determines if a true color image is created, if false an indexed image is created. 00673 */ 00674 static function imageCreate( $width, $height, $isTrueColor = true ) 00675 { 00676 if ( $isTrueColor ) 00677 return ImageCreateTrueColor( $width, $height ); 00678 else 00679 return ImageCreate( $width, $height ); 00680 } 00681 00682 /*! 00683 Creates a geometry array with width \a $width, height \a $height, x position \a $x and y position \a $y and returns it. 00684 */ 00685 static function createGeometry( $width, $height, $x = 0, $y = 0 ) 00686 { 00687 return array( 'x' => $x, 00688 'y' => $y, 00689 'width' => $width, 00690 'height' => $height ); 00691 } 00692 00693 /*! 00694 Creates a new image handler for shell executable from INI settings. 00695 The INI settings are read from ini file \a $iniFilename and group \a $iniGroup. 00696 If \a $iniFilename is not supplied \c image.ini is used. 00697 */ 00698 static function createFromINI( $iniGroup, $iniFilename = false ) 00699 { 00700 if ( !$iniFilename ) 00701 $iniFilename = 'image.ini'; 00702 00703 $handler = false; 00704 $ini = eZINI::instance( $iniFilename ); 00705 if ( !$ini ) 00706 { 00707 eZDebug::writeError( "Failed loading ini file $iniFilename", __METHOD__ ); 00708 return $handler; 00709 } 00710 00711 if ( $ini->hasGroup( $iniGroup ) ) 00712 { 00713 $name = $iniGroup; 00714 if ( $ini->hasVariable( $iniGroup, 'Name' ) ) 00715 $name = $ini->variable( $iniGroup, 'Name' ); 00716 $conversionRules = false; 00717 if ( $ini->hasVariable( $iniGroup, 'ConversionRules' ) ) 00718 { 00719 $conversionRules = array(); 00720 $rules = $ini->variable( $iniGroup, 'ConversionRules' ); 00721 foreach ( $rules as $ruleString ) 00722 { 00723 $ruleItems = explode( ';', $ruleString ); 00724 if ( count( $ruleItems ) >= 2 ) 00725 { 00726 $conversionRules[] = array( 'from' => $ruleItems[0], 00727 'to' => $ruleItems[1] ); 00728 } 00729 } 00730 } 00731 $isEnabled = $ini->variable( $iniGroup, 'IsEnabled' ) == 'true'; 00732 $outputRewriteType = self::REPLACE_SUFFIX; 00733 $handler = new eZImageGDHandler( $name, $isEnabled, 00734 $outputRewriteType, 00735 $conversionRules ); 00736 return $handler; 00737 } 00738 return $handler; 00739 } 00740 00741 /// \privatesection 00742 public $Path; 00743 public $Executable; 00744 public $PreParameters; 00745 public $PostParameters; 00746 } 00747 00748 ?>