* $filters = array( * 1 => array( * 'name' => 'scaleDownByWidth', * 'options' => array( * 'width' => 100 * ), * ), * 2 => array( * 'name' => 'crop', * 'options' => array( * 'startX' => 0, * 'startY' => 0, * 'endX' => 100, * 'endY' => 100, * ), * ), * ); * $mimeTypes = array( 'image/jpeg', 'image/png' ); * * // ezcImageTransformation object returned for further manipulation * $thumbnail = $converter->createTransformation( * 'thumbnail', * $filters, * $mimeTypes * ); * * $converter->transform( 'thumbnail', 'var/storage/myOrinal1.jpg', * 'var/storage/myThumbnail1' ); // res: image/jpeg * $converter->transform( 'thumbnail', 'var/storage/myOrinal2.png', * 'var/storage/myThumbnail2' ); // res: image/png * $converter->transform( 'thumbnail', 'var/storage/myOrinal3.gif', * 'var/storage/myThumbnail3' ); // res: image/.png * * // Animated GIF, will simply be copied! * $converter->transform( 'thumbnail', 'var/storage/myOrinal4.gif', * 'var/storage/myThumbnail4' ); // res: image/gif * * * @see ezcImageConverter * * @package ImageConversion */ class ezcImageTransformation { /** * Array of MIME types allowed as output for this transformation. * Leave empty, for all MIME types to be allowed. * * @var array(string) */ protected $mimeOut; /** * Stores the filters utilized by a transformation. *
     * array(
     *   => array(
     *      'name'    => ,
     *      'options' => array(
     *          ''  => ,
     *          ...
     *      )
     *  ),
     *  ...
     * )
     * 
* * @var array(string) */ protected $filters; /** * Stores the name of this transformation. * * @var string */ protected $name; /** * The ezcImageConverter * * @var object(ezcImageConverter) */ protected $converter; /** * The handler last used for filtering. * * @var object(ezcImageHandler) */ protected $lastHandler; /** * Create a transformation * * @param ezcImageConverter $converter The global converter. * @param string $name Name for the transformation * @param array(ezcImageFilter) $filters Filters to apply * @param array(string) $mimeOut Output MIME types * * @throws ezcImageFiltersException On invalid filter or settings error * @throws ezcImageTransformationException When the output type is unsupported. */ public function __construct( ezcImageConverter $converter, $name, $filters = array(), $mimeOut = array() ) { $this->converter = $converter; $this->name = $name; $this->setFilters( $filters ); $this->setMimeOut( $mimeOut ); } /** * Add a filter to the conversion. * Adds a filter with the specific settings. Filters can be added either * before an existing filter or at the end (leave out $before parameter). * * @param string $name Name of the filter * @param array(string) $options Settings for the filter * @param int $before Where to add the filter * * @throws ezcImageFiltersException On invalid filter or settings error */ public function addFilter( $name, $options, $before = null ) { $filter = array( 'name' => $name, 'options' => $options, ); if ( $this->converter->hasFilter( $name ) === false ) { throw new ezcImageFiltersException( "Filter <{$name}> not available.", ezcImageFiltersException::NOT_AVAILABLE ); } if ( isset( $before ) && isset( $this->filters[$before] ) ) { array_splice( $this->filters, $before, 0, $filter ); return; } $this->filters[] = $filter; } /** * Determine output MIME type * Returns the MIME type that the transformation will output. * * @param string $fileIn File that should deal as input for the transformation. * @param string $mimeIn Specify the MIME type, so method does not need to. * * @return string MIME type the transformation will output. * * @throws ezcImageTransformationException When the input type is unsupported. */ public function getOutMime( $fileIn, $mimeIn = null ) { if ( !isset( $mimeIn ) ) { $analyzer = new ezcImageAnalyzer( $fileIn ); $mimeIn = $analyzer->getMime(); } $mimeOut = $this->converter->getMimeOut( $mimeIn ); // Is output type allowed by this transformation? Else use first allowed one... return in_array( $mimeOut, $this->mimeOut ) ? $mimeOut : reset( $this->mimeOut ); } /** * Apply the given filters for the transformation. * * @param string $fileIn The file to transform. * @param string $fileOut The file to save the transformed image to. */ public function transform( $fileIn, $fileOut ) { // Start atomic file operation $fileTmp = tempnam( dirname( $fileOut ), '.'.basename( $fileOut ) ); copy( $fileIn, $fileTmp ); try { // MIME types $analyzer = new ezcImageAnalyzer( $fileTmp ); // Do not process animated GIFs if ( $analyzer->checkAnimatedGif() ) { copy( $fileTmp, $fileOut ); unlink( $fileTmp ); return; } $mimeIn = $analyzer->getMime(); } catch ( ezcImageAnalyzerException $e ) { // Clean up unlink( $fileTmp ); // Rethrow throw $e; } $outMime = $this->getOutMime( $fileTmp, $mimeIn ); $ref = ''; // Catch exceptions for cleanup try { // Apply the filters foreach ( $this->filters as $filter ) { // Avoid reopening in same handler if ( isset( $this->lastHandler ) ) { if ( $this->lastHandler->hasFilter( $filter['name'] ) ) { $this->lastHandler->applyFilter( $ref, $filter['name'], $filter['options'] ); continue; } else { // Handler does not support filter, save file $this->lastHandler->save( $ref ); $this->lastHandler->close( $ref ); } } // Get handler to perform filter correctly $this->lastHandler = $this->converter->getHandler( $filter['name'], $mimeIn ); $ref = $this->lastHandler->load( $fileTmp, $mimeIn ); $this->lastHandler->applyFilter( $ref, $filter['name'], $filter['options'] ); } // Perform conversion if ( $this->lastHandler->allowsOutput( ( $outMime ) ) ) { $this->lastHandler->convert( $ref, $outMime ); } else { // Close in last handler $this->lastHandler->save( $ref ); $this->lastHandler->close( $ref ); // Retreive correct handler $this->lastHandler = $this->converter->getHandler( null, $mimeIn, $mimeOut ); // Load in new handler $res = $this->lastHandler->load( $fileTmp ); // Perform conversion $this->lastHandler->convert( $ref, $mimeOut ); } // Everything done, save and close $this->lastHandler->save( $ref ); $this->lastHandler->close( $ref ); } catch ( Exception $e ) { // Cleanup $this->lastHandler->close( $ref ); unlink( $fileTmp ); // Rethrow throw $e; } // Finalize atomic file operation rename( $fileTmp, $fileOut ); } /** * Set the filters for this transformation. * Checks if the filters defined are available and saves them to the created * transformation if everything is ok. * * @param array $filters Filter array @link ezcImageTransformation::$filters. * * @throws ezcImageFiltersException * @see ezcImageFiltersException::NOT_AVAILABLE */ protected function setFilters( $filters ) { foreach ( $filters as $id => $filter ) { if ( !$this->converter->hasFilter( $filter['name'] ) ) { throw new ezcImageFiltersException( "Filter <{$filter['name']}> not found!", ezcImageFiltersException::NOT_AVAILABLE ); } $this->filters[$id] = $filter; } } /** * Checks output types if being supported by converter and sets them. * * @param array $mime MIME types to allow output for. * * @throws ezcImageConverterException * @see ezcImageConverterException::MIMETYPE_NOT_AVAILABLE */ protected function setMimeOut( $mime ) { foreach ( $mime as $mimeType ) { if ( !$this->converter->allowsOutput( $mimeType ) ) { throw new ezcImageConverterException( "Converter does not allow output of MIME type <{$mimeType}>.", ezcImageConverterException::MIMETYPE_NOT_AVAILABLE ); } } $this->mimeOut = $mime; } } ?>