• 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.

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();
}
}
 
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.
 
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.

Of to try this on my testbed thanks muchy!

Edit Works fine! :3 <3 thanks alot!
 
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.
 
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?
 
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?
Its not a gallery... Its a library for PHP.
 
ImageMagick support is coming soon, probably with support for the CLI version and the PECL extension for those who have it.

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

Its not a gallery... Its a library for PHP.
But its the raw engine that any serious gallery software needs - I know mine will use it ;)
 
Top Bottom