Apache Zeta Components Manual :: File Source for converter.php

Source for file converter.php

Documentation is available at converter.php

  1. <?php
  2. /**
  3.  * File containing the ezcImageConverter class.
  4.  *
  5.  * Licensed to the Apache Software Foundation (ASF) under one
  6.  * or more contributor license agreements.  See the NOTICE file
  7.  * distributed with this work for additional information
  8.  * regarding copyright ownership.  The ASF licenses this file
  9.  * to you under the Apache License, Version 2.0 (the
  10.  * "License"); you may not use this file except in compliance
  11.  * with the License.  You may obtain a copy of the License at
  12.  * 
  13.  *   http://www.apache.org/licenses/LICENSE-2.0
  14.  * 
  15.  * Unless required by applicable law or agreed to in writing,
  16.  * software distributed under the License is distributed on an
  17.  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  18.  * KIND, either express or implied.  See the License for the
  19.  * specific language governing permissions and limitations
  20.  * under the License.
  21.  *
  22.  * @package ImageConversion
  23.  * @version //autogentag//
  24.  * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
  25.  * @filesource
  26.  */
  27.  
  28. /**
  29.  * Class to manage conversion and filtering of image files.
  30.  * This class is highly recommended to be used with an external
  31.  * singleton pattern to have just 1 converter in place over the whole
  32.  * application.
  33.  *
  34.  * As back-ends 2 handler classes are available, of which at least 1 has to be
  35.  * configured during the instantiation of the ezcImageConverter. Both handlers
  36.  * utilize different image manipulation tools and are capable of different
  37.  * sets of filters:
  38.  *
  39.  * <ul>
  40.  * <li>ezcImageGdHandler
  41.  *  <ul>
  42.  *  <li>Uses PHP's GD extension for image manipulation.</li>
  43.  *  <li>Implements the following filter interfaces
  44.  *   <ul>
  45.  *   <li>{@link ezcImageGeometryFilters}</li>
  46.  *   <li>{@link ezcImageColorspaceFilters}</li>
  47.  *   </ul>
  48.  *  </li>
  49.  *  </ul>
  50.  * </li>
  51.  * <li>ezcImageImagemagickHandler
  52.  *  <ul>
  53.  *  <li>Uses the external "convert" program, contained in ImageMagick</li>
  54.  *  <li>Implements the following interfaces:
  55.  *   <ul>
  56.  *   <li>{@link ezcImageGeometryFilters}</li>
  57.  *   <li>{@link ezcImageColorspaceFilters}</li>
  58.  *   <li>{@link ezcImageEffectFilters}</li>
  59.  *   </ul>
  60.  *  </li>
  61.  *  </ul>
  62.  * </li>
  63.  * </ul>
  64.  *
  65.  * A general example, how to use ezcImageConversion to convert images:
  66.  * <code>
  67.  * // Prepare settings for ezcImageConverter
  68.  * // Defines the handlers to utilize and auto conversions.
  69.  * $settings = new ezcImageConverterSettings(
  70.  *     array(
  71.  *         new ezcImageHandlerSettings( 'GD',          'ezcImageGdHandler' ),
  72.  *         new ezcImageHandlerSettings( 'ImageMagick', 'ezcImageImagemagickHandler' ),
  73.  *     ),
  74.  *     array(
  75.  *         'image/gif' => 'image/png',
  76.  *         'image/bmp' => 'image/jpeg',
  77.  *     )
  78.  * );
  79.  * 
  80.  * // Create the converter itself.
  81.  * $converter = new ezcImageConverter( $settings );
  82.  * 
  83.  * // Define a transformation
  84.  * $filters = array(
  85.  *     new ezcImageFilter(
  86.  *         'scaleWidth',
  87.  *         array(
  88.  *             'width'     => 100,
  89.  *             'direction' => ezcImageGeometryFilters::SCALE_BOTH,
  90.  *         )
  91.  *     ),
  92.  *     new ezcImageFilter(
  93.  *         'colorspace',
  94.  *         array(
  95.  *             'space' => ezcImageColorspaceFilters::COLORSPACE_GREY,
  96.  *         )
  97.  *     ),
  98.  * );
  99.  * 
  100.  * // Which MIME types the conversion may output
  101.  * $mimeTypes = array( 'image/jpeg', 'image/png' );
  102.  * 
  103.  * // Create the transformation inside the manager
  104.  * $converter->createTransformation( 'thumbnail', $filters, $mimeTypes );
  105.  * 
  106.  * // Transform an image.
  107.  * $converter->transform( 'thumbnail', dirname(__FILE__).'/jpeg.jpg', dirname(__FILE__).'/jpeg_thumb.jpg' );
  108.  * </code>
  109.  *
  110.  * It's recommended to create only a single ezcImageConverter instance in your
  111.  * application to avoid creating multiple instances of it's internal objects.
  112.  * You can implement a singleton pattern for this, which might look similar to
  113.  * the following example:
  114.  * <code>
  115.  * function getImageConverterInstance()
  116.  * {
  117.  *     if ( !isset( $GLOBALS['_ezcImageConverterInstance'] ) )
  118.  *     {
  119.  *         // Prepare settings for ezcImageConverter
  120.  *         // Defines the handlers to utilize and auto conversions.
  121.  *         $settings = new ezcImageConverterSettings(
  122.  *             array(
  123.  *                 new ezcImageHandlerSettings( 'GD',          'ezcImageGdHandler' ),
  124.  *                 new ezcImageHandlerSettings( 'ImageMagick', 'ezcImageImagemagickHandler' ),
  125.  *             ),
  126.  *             array(
  127.  *                 'image/gif' => 'image/png',
  128.  *                 'image/bmp' => 'image/jpeg',
  129.  *             )
  130.  *         );
  131.  * 
  132.  * 
  133.  *         // Create the converter itself.
  134.  *         $converter = new ezcImageConverter( $settings );
  135.  * 
  136.  *         // Define a transformation
  137.  *         $filters = array(
  138.  *             new ezcImageFilter(
  139.  *                 'scale',
  140.  *                 array(
  141.  *                     'width'     => 100,
  142.  *                     'height'    => 300,
  143.  *                     'direction' => ezcImageGeometryFilters::SCALE_BOTH,
  144.  *                 )
  145.  *             ),
  146.  *             new ezcImageFilter(
  147.  *                 'colorspace',
  148.  *                 array(
  149.  *                     'space' => ezcImageColorspaceFilters::COLORSPACE_SEPIA,
  150.  *                 )
  151.  *             ),
  152.  *             new ezcImageFilter(
  153.  *                 'border',
  154.  *                 array(
  155.  *                     'width' => 5,
  156.  *                     'color' => array(255, 0, 0),
  157.  *                 )
  158.  *             ),
  159.  *         );
  160.  * 
  161.  *         // Which MIME types the conversion may output
  162.  *         $mimeTypes = array( 'image/jpeg', 'image/png' );
  163.  * 
  164.  *         // Create the transformation inside the manager
  165.  *         $converter->createTransformation( 'funny', $filters, $mimeTypes );
  166.  * 
  167.  *         // Assign singleton instance
  168.  *         $GLOBALS['_ezcImageConverterInstance'] = $converter;
  169.  *     }
  170.  * 
  171.  *     // Return singleton instance
  172.  *     return $GLOBALS['_ezcImageConverterInstance'];
  173.  * }
  174.  * 
  175.  * // ...
  176.  * // Somewhere else in the code...
  177.  * // Transform an image.
  178.  * getImageConverterInstance()->transform( 'funny', dirname(__FILE__).'/jpeg.jpg', dirname(__FILE__).'/jpeg_singleton.jpg' );
  179.  * 
  180.  * </code>
  181.  *
  182.  * @see ezcImageHandler
  183.  * @see ezcImageTransformation
  184.  *
  185.  * @package ImageConversion
  186.  * @version //autogentag//
  187.  * @mainclass
  188.  */
  189. {
  190.     /**
  191.      * Manager settings
  192.      * Settings basis for all image manipulations.
  193.      *
  194.      * @var ezcImageConverterSettings 
  195.      */
  196.     protected $settings;
  197.  
  198.     /**
  199.      * Keeps the handlers used by the converter.
  200.      *
  201.      * @var array(ezcImageHandler) 
  202.      */
  203.     protected $handlers = array();
  204.  
  205.     /**
  206.      * Stores transformation registered with this converter.
  207.      *
  208.      * @var array 
  209.      */
  210.     protected $transformations = array();
  211.  
  212.     /**
  213.      * Initialize converter with settings object.
  214.      * The ezcImageConverter can be directly instantiated, but it's
  215.      * highly recommended to use a manual singleton implementation
  216.      * to have just 1 instance of a ezcImageConverter per Request.
  217.      *
  218.      * ATTENTION: The ezcImageConverter does not support animated
  219.      * GIFs. Animated GIFs will simply be ignored by all filters and
  220.      * conversions.
  221.      *
  222.      * @param ezcImageConverterSettings $settings Settings for the converter.
  223.      *
  224.      * @throws ezcImageHandlerSettingsInvalidException
  225.      *          If handler settings are invalid.
  226.      * @throws ezcImageMimeTypeUnsupportedException
  227.      *          If a given MIME type is not supported.
  228.      */
  229.     public function __constructezcImageConverterSettings $settings )
  230.     {
  231.         // Initialize handlers
  232.         foreach $settings->handlers as $i => $handlerSettings )
  233.         {
  234.             if !$handlerSettings instanceof ezcImageHandlerSettings )
  235.             {
  236.                 throw new ezcImageHandlerSettingsInvalidException();
  237.             }
  238.             $handlerClass $handlerSettings->className;
  239.             if !ezcBaseFeatures::classExists$handlerClass ) )
  240.             {
  241.                 throw new ezcImageHandlerNotAvailableException$handlerClass );
  242.             }
  243.             $handler new $handlerClass$handlerSettings );
  244.             $this->handlers[$handlerSettings->referenceName$handler;
  245.         }
  246.         // Check implicit conversions
  247.         foreach $settings->conversions as $mimeIn => $mimeOut )
  248.         {
  249.             if !$this->allowsInput$mimeIn ) )
  250.             {
  251.                 throw new ezcImageMimeTypeUnsupportedException$mimeIn'input' );
  252.             }
  253.             if !$this->allowsOutput$mimeOut ) )
  254.             {
  255.                 throw new ezcImageMimeTypeUnsupportedException$mimeOut'output' );
  256.             }
  257.         }
  258.         $this->settings = $settings;
  259.     }
  260.  
  261.     /**
  262.      * Create a transformation in the manager.
  263.      *
  264.      * Creates a transformation and stores it in the manager. A reference to the
  265.      * transformation is returned by this method for further manipulation and
  266.      * to set options on it. The $name can later be used to remove a
  267.      * transfromation using {@link removeTransformation()} or to execute it
  268.      * using {@link transform()}. The $filters and $mimeOut parameters specify
  269.      * the transformation actions as described with {@link }
  270.      * ezcImageTransformation::__construct()}. The $saveOptions are used when
  271.      * the finally created image is saved and can configure compression and
  272.      * quality options.
  273.      *
  274.      * @param string                $name        Name for the transformation.
  275.      * @param array(ezcImageFilter) $filters     Filters.
  276.      * @param array(string)         $mimeOut     Output MIME types.
  277.      * @param ezcImageSaveOptions   $saveOptions Save options.
  278.      *
  279.      * @return ezcImageTransformation 
  280.      *
  281.      * @throws ezcImageFiltersException
  282.      *          If a given filter does not exist.
  283.      * @throws ezcImageTransformationAlreadyExists
  284.      *          If a transformation with the given name does already exist.
  285.      */
  286.     public function createTransformation$namearray $filtersarray $mimeOutezcImageSaveOptions $saveOptions null )
  287.     {
  288.         if isset$this->transformations[$name) )
  289.         {
  290.             throw new ezcImageTransformationAlreadyExistsException$name );
  291.         }
  292.         $this->transformations[$namenew ezcImageTransformation$this$name$filters$mimeOut$saveOptions );
  293.         return $this->transformations[$name];
  294.     }
  295.  
  296.     /**
  297.      * Removes a transformation from the manager.
  298.      *
  299.      * @param string $name Name of the transformation to remove
  300.      *
  301.      * @return ezcImageTransformation The removed transformation
  302.      *
  303.      * @throws ezcImageTransformationNotAvailableExeption
  304.      *          If the requested transformation is unknown.
  305.      */
  306.     public function removeTransformation$name )
  307.     {
  308.         if !isset$this->transformations[$name) )
  309.         {
  310.             throw new ezcImageTransformationNotAvailableException$name );
  311.         }
  312.         unset$this->transformations[$name);
  313.     }
  314.  
  315.     /**
  316.      * Apply transformation on a file.
  317.      * This applies the given transformation to the given file.
  318.      *
  319.      * @param string $name    Name of the transformation to perform
  320.      * @param string $inFile  The file to transform
  321.      * @param string $outFile The file to save transformed version to
  322.      *
  323.      * @throws ezcImageTransformationNotAvailableExeption
  324.      *          If the requested transformation is unknown.
  325.      * @throws ezcImageTransformationException If an error occurs during the
  326.      *          transformation. The returned exception contains the exception
  327.      *          the problem resulted from in it's public $parent attribute.
  328.      * @throws ezcBaseFileNotFoundException If the file you are trying to
  329.      *          transform does not exists.
  330.      * @throws ezcBaseFilePermissionException If the file you are trying to
  331.      *          transform is not readable.
  332.      */
  333.     public function transform$name$inFile$outFile )
  334.     {
  335.         if !isset$this->transformations[$name) )
  336.         {
  337.             throw new ezcImageTransformationNotAvailableException$name );
  338.         }
  339.         $this->transformations[$name]->transform$inFile$outFile );
  340.     }
  341.  
  342.     /**
  343.      * Returns if a handler is found, supporting the given MIME type for output.
  344.      *
  345.      * @param string $mime The MIME type to check for.
  346.      * @return bool Whether the MIME type is supported.
  347.      */
  348.     public function allowsInput$mime )
  349.     {
  350.         foreach $this->handlers as $handler )
  351.         {
  352.             if $handler->allowsInput$mime ) )
  353.             {
  354.                 return true;
  355.             }
  356.         }
  357.         return false;
  358.     }
  359.  
  360.     /**
  361.      * Returns if a handler is found, supporting the given MIME type for output.
  362.      *
  363.      * @param string $mime The MIME type to check for.
  364.      * @return bool Whether the MIME type is supported.
  365.      */
  366.     public function allowsOutput$mime )
  367.     {
  368.         foreach $this->handlers as $handler )
  369.         {
  370.             if $handler->allowsOutput$mime ) )
  371.             {
  372.                 return true;
  373.             }
  374.         }
  375.         return false;
  376.     }
  377.  
  378.     /**
  379.      * Returns the MIME type that will be outputted for a given input type.
  380.      * Checks whether the given input type can be processed. If not, an
  381.      * exception is thrown. Checks then, if an implicit conversion for that
  382.      * MIME type is defined. If so, outputs the given output MIME type. In
  383.      * every other case, just outputs the MIME type given, because no
  384.      * conversion is implicitly required.
  385.      *
  386.      * @param string $mimeIn Input MIME type.
  387.      * @return string Output MIME type.
  388.      *
  389.      * @throws ezcImageMimeTypeUnsupportedException
  390.      *          If the input MIME type is not supported.
  391.      */
  392.     public function getMimeOut$mimeIn )
  393.     {
  394.         if $this->allowsInput$mimeIn === false )
  395.         {
  396.             throw new ezcImageMimeTypeUnsupportedException$mimeIn'input' );
  397.         }
  398.         if isset$this->settings->conversions[$mimeIn) )
  399.         {
  400.             return $this->settings->conversions[$mimeIn];
  401.         }
  402.         return $mimeIn;
  403.     }
  404.  
  405.     /**
  406.      * Returns if a given filter is available.
  407.      * Returns either an array of handler names this filter
  408.      * is available in or false if the filter is not enabled.
  409.      *
  410.      * @param string $name Name of the filter to query existance for
  411.      *
  412.      * @return mixed Array of handlers on success, otherwise false.
  413.      */
  414.     public function hasFilter$name )
  415.     {
  416.         foreach $this->handlers as $handler )
  417.         {
  418.             if $handler->hasFilter$name ) )
  419.             {
  420.                 return true;
  421.             }
  422.         }
  423.         return false;
  424.     }
  425.  
  426.     /**
  427.      * Returns a list of enabled filters.
  428.      * Gives you an overview on filters enabled in the manager.
  429.      * Format is:
  430.      * <code>
  431.      * array(
  432.      *  '<filterName>',
  433.      * );
  434.      * </code>
  435.      *
  436.      * @return array(string) 
  437.      */
  438.     public function getFilterNames()
  439.     {
  440.         $filters array();
  441.         foreach $this->handlers as $handler )
  442.         {
  443.             $filters array_merge$filters$handler->getFilterNames() );
  444.         }
  445.         return array_unique$filters );
  446.     }
  447.  
  448.     /**
  449.      * Apply a single filter to an image.
  450.      * Applies just a single filter to an image. Optionally you can select
  451.      * a handler yourself, which is not recommended, but possible. If the
  452.      * specific handler does not have that filter, ImageConverter will try
  453.      * to fall back on another handler.
  454.      *
  455.      * @param ezcImageFilter $filter      Filter object to apply.
  456.      * @param string         $inFile      Name of the input file.
  457.      * @param string         $outFile     Name of the output file.
  458.      * @param string         $handlerName 
  459.      *         To choose a specific handler, this is the reference named passed
  460.      *         to {@link ezcImageHandlerSettings}.
  461.      * @return void 
  462.      *
  463.      *
  464.      * @throws ezcImageHandlerNotAvailableException
  465.      *          If fitting handler is not available.
  466.      * @throws ezcImageFilterNotAvailableException
  467.      *          If filter is not available.
  468.      * @throws ezcImageFileNameInvalidException
  469.      *          If an invalid character (", ', $) is found in the file name.
  470.      */
  471.     public function applyFilterezcImageFilter $filter$inFile$outFile$handlerName null )
  472.     {
  473.         $handlerObj false;
  474.         // Do we have an explicit handler given?
  475.         if $handlerName !== null )
  476.         {
  477.             if !isset$this->handlers[$handlerName) )
  478.             {
  479.                 throw new ezcImageHandlerNotAvailableException$handlerName );
  480.             }
  481.             if $this->handlers[$handlerName]->hasFilter$filter->name === true )
  482.             {
  483.                 $handlerObj $this->handlers[$handlerName];
  484.             }
  485.         }
  486.         // Either no handler explicitly given or try to fall back.
  487.         if $handlerObj === false )
  488.         {
  489.             foreach $this->handlers as $regHandler )
  490.             {
  491.                 if $regHandler->hasFilter$filter->name ) )
  492.                 {
  493.                     $handlerObj $regHandler;
  494.                     break;
  495.                 }
  496.             }
  497.         }
  498.         // No handler found to apply filter with.
  499.         if $handlerObj === false )
  500.         {
  501.             throw new ezcImageFilterNotAvailableException$filter->name );
  502.         }
  503.         $imgRef $handlerObj->load$inFile );
  504.         $handlerObj->applyFilter$imgRef$filter );
  505.         $handlerObj->save$imgRef$outFile );
  506.     }
  507.  
  508.     /**
  509.      * Returns a handler object for direct use.
  510.      * Returns the handler with the highest priority, that supports the given
  511.      * filter, MIME input type and MIME output type. All parameters are
  512.      * optional, if none is specified, the highest prioritized handler is
  513.      * returned.
  514.      *
  515.      * If no handler is found, that supports the criteria named, an exception
  516.      * of type {@link ezcImageHandlerNotAvailableException} will be thrown.
  517.      *
  518.      * @param string $filterName  Name of the filter to search for.
  519.      * @param string $mimeIn      Input MIME type.
  520.      * @param string $mimeOut     Output MIME type.
  521.      *
  522.      * @return ezcImageHandler 
  523.      *
  524.      * @throws ezcImageHandlerNotAvailableException
  525.      *          If a handler for the given specification could not be found.
  526.      */
  527.     public function getHandler$filterName null$mimeIn null$mimeOut null )
  528.     {
  529.         foreach $this->handlers as $handler )
  530.         {
  531.             if ( ( !isset$filterName || $handler->hasFilter$filterName ) )
  532.               && !isset$mimeIn )     || $handler->allowsInput$mimeIn ) )
  533.               && !isset$mimeOut )    || $handler->allowsOutput$mimeOut ) )
  534.                )
  535.             {
  536.                 return $handler;
  537.             }
  538.         }
  539.         throw new ezcImageHandlerNotAvailableException'unknown' );
  540.     }
  541. }
  542. ?>
Documentation generated by phpDocumentor 1.4.3