1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. This forum has been archived. New threads and replies may not be made. All add-ons/resources that are active should be migrated to the Resource Manager. See this thread for more information.

Imagick Image library.

Discussion in 'Tips and Guides [Archive]' started by Thalagyrt, Apr 24, 2011.

  1. Thalagyrt

    Thalagyrt Member

    I hacked this together a while back because animated avatars were and are are a staple of my board. Figured I'd mention it since every upgrade to XF has involved me changing the abstract class to point back to my Imagick library.

    It's a bit of a hack and for some operations relies on shell calls, just because I wanted it done quickly.

    That said, maybe with a bit of fixing to not use shell calls but instead 100% imagick bindings this could end up in XF as an option for admins who want animated avatars?

    If you want to use this currently, at your own risk of course, you can just drop it in library/XenForo/Image/Imagick.php and change Abstract.php to point to Xenforo_Image_Imagick instead of Xenforo_Image_Gd. You'd also need to fix the paths to binaries, /tmp if applicable, etc. Been using this for 3 months now with no issues at all. Thoughts? I'd imagine it could boil down to a simple config.php setting for Gd or Imagick.

    Code:
    <?php
    
    /**
    * Image processor using GD.
    *
    * @package XenForo_Image
    */
    class XenForo_Image_Imagick extends XenForo_Image_Abstract
    {
    /**
    * The GD image resource.
    *
    * @var resource
    */
    protected $_image;
    
    /**
    * Constructor.
    *
    * @param resource $image GD image resource
    */
    protected function __construct($image)
    {
    $this->_setImage($image);
    }
    
    /**
    * Creates a blank image.
    *
    * @param integer $width
    * @param integer $height
    *
    * @return XenForo_Image_Gd
    */
    public static function createImageDirect($width, $height)
    {
    $image = new Imagick();
    $image->newImage($width, $height, new ImagickPixel('white'));
    $image->setImageFormat('png');
    return new self($image);
    }
    
    /**
    * Creates an image from an existing file.
    *
    * @param string $fileName
    * @param integer $inputType IMAGETYPE_XYZ constant representing image type
    *
    * @return XenForo_Image_Gd
    */
    public static function createFromFileDirect($fileName, $inputType)
    {
    $invalidType = false;
    
    try
    {
    $image = new Imagick();
    $image->readImage($fileName);
    }
    catch (Exception $e)
    {
    return false;
    }
    
    if ($invalidType)
    {
    throw new XenForo_Exception('Invalid image type given. Expects IMAGETYPE_XXX constant.');
    }
    
    return new self($image);
    }
    
    /**
    * Thumbnails the image.
    *
    * @see XenForo_Image_Abstract::thumbnail()
    */
    public function thumbnail($maxWidth, $maxHeight = 0)
    {
    if ($maxWidth < 10)
    {
    $maxWidth = 10;
    }
    if ($maxHeight < 10)
    {
    $maxHeight = $maxWidth;
    }
    
    if ($this->_width < $maxWidth && $this->_height < $maxHeight)
    {
    return false;
    }
    
    $ratio = $this->_width / $this->_height;
    
    $maxRatio = ($maxWidth / $maxHeight);
    
    if ($maxRatio > $ratio)
    {
    $width = max(1, $maxHeight * $ratio);
    $height = $maxHeight;
    }
    else
    {
    $width = $maxWidth;
    $height = max(1, $maxWidth / $ratio);
    }
    
    $a = tempnam("/tmp","avi_");
    $b = tempnam("/tmp","avo_");
    $this->_image->writeImages($a, true);
    exec('/usr/bin/convert '.$a.' -coalesce -bordercolor White -border 0 -resize '.$width.'x'.$height.' '.$b);
    
    $this->_image->clear();
    $this->_image->readImage($b);
    
    unlink($a);
    unlink($b);
    
    $this->_setImage($this->_image);
    }
    
    /**
    * Produces a thumbnail of the current image whose shorter side is the specified length
    *
    * @see XenForo_Image_Abstract::thumbnailFixedShorterSide
    */
    public function thumbnailFixedShorterSide($shortSideLength)
    {
    if ($shortSideLength < 10)
    {
    $shortSideLength = 10;
    }
    
    $ratio = $this->_width / $this->_height;
                    if ($ratio > 1) // landscape
                    {
                            $width = $shortSideLength * $ratio;
                            $height = $shortSideLength;
                    }
                    else
                    {
                            $width = $shortSideLength;
                            $height = max(1, $shortSideLength / $ratio);
                    }
    
    $a = tempnam("/tmp","avi_");
    $b = tempnam("/tmp","avo_");
    $this->_image->writeImages($a, true);
    exec('/usr/bin/convert '.$a.' -coalesce -bordercolor White -border 0 -resize '.$width.'x'.$height.' '.$b);
    
    $this->_image->clear();
    $this->_image->readImage($b);
    
    unlink($a);
    unlink($b);
    
    $this->_setImage($this->_image);
    }
    
    /**
    * Crops the image.
    *
    * @see XenForo_Image_Abstract::crop()
    */
    public function crop($x, $y, $width, $height)
    {
    error_log("$x $y $width $height");
    
    $a = tempnam("/tmp","avi_");
    $b = tempnam("/tmp","avo_");
    $this->_image->writeImages($a, true);
    exec('/usr/bin/convert '.$a.' -crop '.$width.'x'.$height.'+'.$x.'+'.$y.' +repage '.$b);
    
    $this->_image->clear();
    $this->_image->readImage($b);
    
    unlink($a);
    unlink($b);
    
    $this->_setImage($this->_image);
    }
    
    /**
    * Outputs the image.
    *
    * @see XenForo_Image_Abstract::output()
    */
    public function output($outputType, $outputFile = null, $quality = 85)
    {
    switch ($outputType)
    {
    case IMAGETYPE_GIF: $this->_image->setImageFormat('gif'); break;
    case IMAGETYPE_JPEG: $this->_image->setImageFormat('jpeg'); break;
    case IMAGETYPE_PNG: $this->_image->setImageFormat('png'); break;
    
    default:
    throw new XenForo_Exception('Invalid output type given. Expects IMAGETYPE_XXX constant.');
    
    }
    return $this->_image->writeImages($outputFile, true);
    }
    
    protected function _preallocateBackground($image)
    {
    // Not necessary
    }
    
    /**
    * Sets the internal GD image resource.
    *
    * @param resource $image
    */
    protected function _setImage($image)
    {
    $this->_image = $image;
    $this->_width = $image->getImageWidth();
    $this->_height = $image->getImageHeight();
    }
    }
     
  2. gib

    gib Active Member

    thanks for that I will give it a try.

    I would love to see an imagick option in xenForo, it's the only thing that stops me running my site on a shared host, so it's costing me a fair bit on a dedicated host with more memory on it.

    the GD library runs out of memory very quickly, when resizing medium size jpg's
    imagick doesn't grumble and would work well on a shared host.
     
  3. Wuebit

    Wuebit Well-Known Member

    Of to try this on my testbed thanks muchy!

    Edit Works fine! :3 <3 thanks alot!
     
  4. MGSteve

    MGSteve Well-Known Member

    imagemagik (and even magickWand) should really be supported within XF as they're pretty common now. Ok, perhaps not the wand extension, but definitely IM.
     
  5. Kier

    Kier XenForo Developer Staff Member

    ImageMagick support is coming soon, probably with support for the CLI version and the PECL extension for those who have it.
     
    bubbl3, Thalagyrt, Alien and 9 others like this.
  6. Ryan Kent

    Ryan Kent Well-Known Member

    What benefits does Imagick offer to us? Can anyone please elaborate?

    I am very much in need of a image gallery for my site. I would strongly prefer a XF solution rather then a 3rd party app. Would Imagick help with that?
     
  7. Kier

    Kier XenForo Developer Staff Member

    ImageMagick supports resizing animated images for a start...
     
  8. Forsaken

    Forsaken Well-Known Member

    Its not a gallery... Its a library for PHP.
     
    Vodkaholic likes this.
  9. MGSteve

    MGSteve Well-Known Member

    "PECL extension" - is that the same as the MagickWand extension or a different one?

    But its the raw engine that any serious gallery software needs - I know mine will use it ;)
     
  10. Kier

    Kier XenForo Developer Staff Member

  11. masterchief

    masterchief Well-Known Member

  12. Ryan Kent

    Ryan Kent Well-Known Member

  13. masterchief

    masterchief Well-Known Member

Share This Page