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