mambax7/extgallery

View on GitHub
class/pear/Image/Transform/Driver/IM.php

Summary

Maintainability
A
0 mins
Test Coverage
<?php

/* vim: set expandtab tabstop=4 shiftwidth=4: */

/**
 * ImageMagick binaries implementation for Image_Transform package
 *
 * PHP versions 4 and 5
 *
 * LICENSE: This source file is subject to version 3.0 of the PHP license
 * that is available through the world-wide-web at the following URI:
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
 * the PHP License and are unable to obtain it through the web, please
 * send a note to license@php.net so we can mail you a copy immediately.
 *
 * @category   Image
 * @package    Image_Transform
 * @author     Peter Bowyer <peter@mapledesign.co.uk>
 * @author     Philippe Jausions <Philippe.Jausions@11abacus.com>
 * @copyright  2002-2005 The PHP Group
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
 * @version    CVS: $Id: IM.php 266859 2008-09-30 22:28:47Z dufuz $
 * @link       http://pear.php.net/package/Image_Transform
 */

//require_once __DIR__ . '/Image/Transform.php';
//require_once __DIR__ . '/System.php';
require_once XOOPS_ROOT_PATH . '/modules/extgallery/class/pear/Image/Transform.php';
require_once XOOPS_ROOT_PATH . '/modules/extgallery/class/pear/System.php';

/**
 * ImageMagick binaries implementation for Image_Transform package
 *
 * @category   Image
 * @package    Image_Transform
 * @subpackage Image_Transform_Driver_IM
 * @author     Peter Bowyer <peter@mapledesign.co.uk>
 * @author     Philippe Jausions <Philippe.Jausions@11abacus.com>
 * @copyright  2002-2005 The PHP Group
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
 * @version    Release: @package_version@
 * @link       http://pear.php.net/package/Image_Transform
 * @link       http://www.imagemagick.org/
 **/
class Image_Transform_Driver_IM extends Image_Transform
{
    /**
     * associative array commands to be executed
     * @var array
     * @access private
     */
    public $command;

    /**
     * Class constructor
     */
    public function Image_Transform_Driver_IM()
    {
        $this->__construct();
    }

    // End Image_IM

    /**
     * Class constructor
     */
    public function __construct()
    {
        $this->_init();
        if (!defined('IMAGE_TRANSFORM_IM_PATH')) {
            $path = \dirname(System::which('convert')) . DIRECTORY_SEPARATOR;
            define('IMAGE_TRANSFORM_IM_PATH', $path);
        }
        if (System::which(IMAGE_TRANSFORM_IM_PATH . 'convert' . (OS_WINDOWS ? '.exe' : ''))) {
            require_once __DIR__ . '/Image/Transform/Driver/Imagick/ImageTypes.php';
        } else {
            $this->isError(PEAR::raiseError('Couldn\'t find "convert" binary', IMAGE_TRANSFORM_ERROR_UNSUPPORTED));
        }
    }

    // End Image_IM

    /**
     * Initialize the state of the object
     **/
    public function _init()
    {
        $this->command = [];
    }

    /**
     * Load an image.
     *
     * This method doesn't support remote files.
     *
     * @param mixed $image
     *
     * @return mixed TRUE or a PEAR error object on error
     * @see PEAR::isError()
     */
    public function load($image)
    {
        $this->_init();
        if (!file_exists($image)) {
            return PEAR::raiseError('The image file ' . $image . ' doesn\'t exist', IMAGE_TRANSFORM_ERROR_IO);
        }
        $this->image = $image;
        $result      = $this->_get_image_details($image);
        if (PEAR::isError($result)) {
            return $result;
        }

        return true;
    }

    // End load

    /**
     * Image_Transform_Driver_IM::_get_image_details()
     *
     * @param string $image the path and name of the image file
     * @return none
     */
    public function _get_image_details($image)
    {
        $retval = Image_Transform::_get_image_details($image);
        if (PEAR::isError($retval)) {
            unset($retval);

            if (!System::which(IMAGE_TRANSFORM_IM_PATH . 'identify' . (OS_WINDOWS ? '.exe' : ''))) {
                $this->isError(PEAR::raiseError('Couldn\'t find "identify" binary', IMAGE_TRANSFORM_ERROR_UNSUPPORTED));
            }
            $cmd = $this->_prepare_cmd(IMAGE_TRANSFORM_IM_PATH, 'identify', '-format %w:%h:%m ' . escapeshellarg($image));
            exec($cmd, $res, $exit);

            if (0 != $exit) {
                return PEAR::raiseError('Cannot fetch image or images details.', true);
            }

            $data        = explode(':', $res[0]);
            $this->img_x = $data[0];
            $this->img_y = $data[1];
            $this->type  = mb_strtolower($data[2]);
            $retval      = true;
        }

        return $retval;
    }

    /**
     * Resize the image.
     *
     * @access private
     *
     * @param int   $new_x   New width
     * @param int   $new_y   New height
     * @param mixed $options Optional parameters
     *
     * @return true on success or PEAR Error object on error
     * @see    PEAR::isError()
     */
    public function _resize($new_x, $new_y, $options = null)
    {
        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 ' . ((int)$new_x) . 'x' . ((int)$new_y) . '!';

        $this->new_x = $new_x;
        $this->new_y = $new_y;

        return true;
    }

    // End resize

    /**
     * rotate
     *
     * @param      $angle
     * @param null $options
     * @return mixed TRUE or a PEAR error object on error
     */
    public function rotate($angle, $options = null)
    {
        $angle = $this->_rotation_angle($angle);
        if ($angle % 360) {
            $this->command['rotate'] = '-rotate ' . (float)$angle;
        }

        return true;
    }

    // End rotate

    /**
     * Crop image
     *
     * @param mixed $width
     * @param mixed $height
     * @param mixed $x
     * @param mixed $y
     *
     * @return mixed TRUE or a PEAR error object on error
     * @since  0.8
     *
     * @author Ian Eure <ieure@websprockets.com>
     */
    public function crop($width, $height, $x = 0, $y = 0)
    {
        // Do we want a safety check - i.e. if $width+$x > $this->img_x then we
        // raise a warning? [and obviously same for $height+$y]
        $this->command['crop'] = '-crop ' . ((int)$width) . 'x' . ((int)$height) . '+' . ((int)$x) . '+' . ((int)$y) . '!';

        // I think that setting img_x/y is wrong, but scaleByLength() & friends
        // mess up the aspect after a crop otherwise.
        $this->new_x = $this->img_x = $width - $x;
        $this->new_y = $this->img_y = $height - $y;

        return true;
    }

    /**
     * addText
     *
     * @param mixed $params
     *
     * @return mixed TRUE or a PEAR error object on error
     * @see PEAR::isError()
     */
    public function addText($params)
    {
        $this->old_image = $this->imageHandle;
        $params          = array_merge($this->_get_default_text_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 ' . escapeshellarg($font) . ' -fill ' . escapeshellarg($color) . ' -draw \'text ' . escapeshellarg($x . ',' . $y) . ' "' . escapeshellarg($text) . '"\'';

        // Producing error: gs: not found gs: not found convert: Postscript delegate failed [No such file or directory].
        return true;
    }

    // End addText

    /**
     * Adjust the image gamma
     *
     * @access public
     * @param float $outputgamma
     * @return mixed TRUE or a PEAR error object on error
     */
    public function gamma($outputgamma = 1.0)
    {
        if (1.0 != $outputgamme) {
            $this->command['gamma'] = '-gamma ' . (float)$outputgamma;
        }

        return true;
    }

    /**
     * Convert the image to greyscale
     *
     * @access public
     * @return mixed TRUE or a PEAR error object on error
     */
    public function greyscale()
    {
        $this->command['type'] = '-type Grayscale';

        return true;
    }

    /**
     * Horizontal mirroring
     *
     * @access public
     * @return true or PEAR Error object on error
     */
    public function mirror()
    {
        // We can only apply "flop" once
        if (isset($this->command['flop'])) {
            unset($this->command['flop']);
        } else {
            $this->command['flop'] = '-flop';
        }

        return true;
    }

    /**
     * Vertical mirroring
     *
     * @access public
     * @return true or PEAR Error object on error
     */
    public function flip()
    {
        // We can only apply "flip" once
        if (isset($this->command['flip'])) {
            unset($this->command['flip']);
        } else {
            $this->command['flip'] = '-flip';
        }

        return true;
    }

    /**
     * Save the image file
     *
     * @access public
     *
     * @param string  $filename the name of the file to write to
     * @param quality $quality  image dpi, default=75
     * @param string  $type     (JPEG, PNG...)
     *
     * @return mixed TRUE or a PEAR error object on error
     */
    public function save($filename, $type = '', $quality = null)
    {
        $type = mb_strtoupper(('' == $type) ? $this->type : $type);
        switch ($type) {
            case 'JPEG':
                $type = 'JPG';
                break;
        }
        $options = [];
        if (null !== $quality) {
            $options['quality'] = $quality;
        }
        $quality = $this->_getOption('quality', $options, 75);

        $cmd = $this->_prepare_cmd(IMAGE_TRANSFORM_IM_PATH, 'convert', implode(' ', $this->command) . ' -quality ' . ((int)$quality) . ' ' . escapeshellarg($this->image) . ' ' . $type . ':' . escapeshellarg($filename) . ' 2>&1');
        exec($cmd, $res, $exit);

        if (!$this->keep_settings_on_save) {
            $this->free();
        }

        return (0 == $exit) ? true : PEAR::raiseError(implode('. ', $res), IMAGE_TRANSFORM_ERROR_IO);
    }

    // End save

    /**
     * Display image without saving and lose changes
     *
     * This method adds the Content-type HTTP header
     *
     * @access public
     *
     * @param mixed      $type
     * @param null|mixed $quality
     *
     * @return mixed TRUE or a PEAR error object on error
     */
    public function display($type = '', $quality = null)
    {
        $type = mb_strtoupper(('' == $type) ? $this->type : $type);
        switch ($type) {
            case 'JPEG':
                $type = 'JPG';
                break;
        }
        $options = [];
        if (null !== $quality) {
            $options['quality'] = $quality;
        }
        $quality = $this->_getOption('quality', $options, 75);

        $this->_send_display_headers($type);

        $cmd = $this->_prepare_cmd(IMAGE_TRANSFORM_IM_PATH, 'convert', implode(' ', $this->command) . " -quality $quality " . $this->image . ' ' . $type . ':-');
        passthru($cmd);

        if (!$this->keep_settings_on_save) {
            $this->free();
        }

        return true;
    }

    /**
     * Destroy image handle
     */
    public function free()
    {
        $this->command = [];
        $this->image   = '';
        $this->type    = '';
    }
} // End class ImageIM