/Main_Page

::You must have ninja focus to complete your mission::NinjaFocus::

PHP Image Manipulation

Views:


Image resizing and scaling. Requires that you install the (long dead?) MagickWand extension for PHP.

<?php
/**
 * @package ninja
 * @copyright Kieran Whitbread 2006-2010
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 */
class NinjaJpegImage extends NinjaImage
{
    public function __construct($image)
    {
        parent::__construct($image);
		MagickSetFormat($this->magickWand, 'JPG');
		MagickSetImageCompression($this->magickWand, MW_JPEGCompression);
		MagickSetImageCompressionQuality($this->magickWand, 80.0);
    }
}

<?php
/**
 * @package ninja
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 * @copyright Kieran Whitbread 2006-2010
 */
class NinjaImage
{
    protected $blob = NULL;
    protected $filename = NULL;
    protected $magickWand = NULL;
    // Don't attempt to load an image larger than the following number of bytes
    const MAX_SIZE = 1048576; // 1MB

    public function __construct($image)
    {
    	$this->magickWand = NewMagickWand();
        if ($image)
        {
            if (is_string($image) && is_file($image) && MagickPingImage($this->magickWand, $image) && (filesize($image) <= self::MAX_SIZE))
            {   
            	$handle = fopen($image, 'r');
                MagickReadImageFile($this->magickWand, $handle);
                $this->filename = $image;
            }
            elseif (strlen($image) <= self::MAX_SIZE)
            {
                MagickReadImageBlob($this->magickWand, $image);
            }
            // Check Magick Error Status Here!!
        }
    }
    public function __sleep()
    {
        $this->blob = $this->get_blob();
        ClearMagickWand($this->magickWand);
        DestroyMagickWand($this->magickWand);
        return array_keys(get_object_vars($this));
    }
    public function __wakeup()
    {
        $this->magickWand = NewMagickWand();
        $this->image = MagickReadImageBlob($this->magickWand, $this->blob);
    }
    public function crop($xColumns, $yColumns, $xOffset=0, $yOffset=0)
    {
        if (is_int($xColumns) && is_int($yColumns) && is_int($xOffset) && is_int($yOffset))
        {
            return MagickCropImage($xColumns, $yColumns, $xOffset, $yOffset);
        }
        return false;
    }
    public function get_blob()
    {
        return MagickGetImageBlob($this->magickWand);
    }
    public function get_height()
    {
        return MagickGetImageHeight($this->magickWand);
    }
    public function get_image()
    {
        return MagickGetImage($this->magickWand);
    }
	public function get_image_size()
	{
		MagickGetImageSize($this->magickWand);
	}
    public function get_mime_type()
    {
        return MagickGetMimeType($this->magickWand);
    }
	public static function getScaleSizes($currentX, $currentY, $maxX, $maxY)
	{
        $result = false;
        $newX = null;
        $newY = null;
        $sourceRatio = ($currentX / $currentY);
        $targetRatio = ($maxX / $maxY);
        if ($sourceRatio >= $targetRatio)
        {
            $newX = $maxX;
            $newY = round($currentY /($currentX / $maxX));
        }
        elseif ($sourceRatio < $targetRatio)
        {
            $newY = $maxY;
            $newX = round($currentX / ($currentY/$newY));
        }
        $result = array($newX, $newY);   
        return $result;
	}
	
    public function get_width()
    {
        return MagickGetImageWidth($this->magickWand);
    }
    public function resize($x = NULL, $y = NULL)
    {
    	$result = false;
        $newX = NULL;
        $newY = NULL;
        $currentX = $this->get_width();
        $currentY = $this->get_height();
        if (!is_null($x) && preg_match(NINJA_PREG_UINT, $x) && ($x > 0))
        {
            $newX = $x;
        }
        if (!is_null($y) && preg_match(NINJA_PREG_UINT, $y) && ($y > 0))
        {
            $newY = $y;
        }
        
        if ($newX || $newY)
        {
            if (!$newX)
            {
                $newX = round($currentX * ($newY / $currentY));
            }
            elseif (!$newY)
            {
                $newY = round($currentY * ($newX / $currentX));
            }
            $result = MagickResizeImage($this->magickWand, $newX, $newY, MW_QuadraticFilter, 1.0);
        }
        return $result;
    }
    public function rotate($degrees)
    {
        if (is_int($degrees) && ($degrees <= 360) && ($degrees >= -360))
        {
            return MagickRotateImage($this->magickWand, NULL, $degrees);
        }
        return false;
    }
	public function save($path)
	{
		try
		{
			$file = new SplFileObject($path, 'w');
		}
		catch (Exception $e)
		{
			return false;
		}
		$blob = $this->get_blob();
		$file->fwrite($blob);
		$file->fflush();
	}
	public function scaleToFit($x=null, $y=null)
	{
        if (!$x && !$y) return null;
        $dimensions = $this->getScaleSizes($this->get_width(), $this->get_height(), $x, $y);
        $result = MagickResizeImage($this->magickWand, $dimensions[0], $dimensions[1], MW_QuadraticFilter, 1.0);
        return $result;
	}
    public function send($headers = array())
    {
		if (!is_array($headers)) $headers = array();
		$headers['Accept-Ranges'] = 'none';
		$headers['Content-Type'] = $this->get_mime_type();
		$headers['Content-Length'] = $this->get_image_size();
		foreach ($headers as $name => $value)
		{
			header("$name: $value");
		}
        MagickEchoImageBlob($this->magickWand);
    }
}

Main Menu

Personal tools

Toolbox