• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.
  • 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.

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

gib

Active member
#2
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.
 

DarkVodka

Formerly Wuebit
#3
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!
 

MGSteve

Well-known member
#4
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.
 

Ryan Kent

Well-known member
#6
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?
 

Forsaken

Well-known member
#8
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.