Image adapters have been tested during development, but needs some more real world examples to ensure consistent and desired behavior.
The ImageHandler-class is still outstanding, will be included with the upcoming commits, leaving the image adapters almost useless for now.
<?php
-class GDImageAdapter {
+namespace wcf\system\image\adapter;
+
+/**
+ * Image adapter for bundled GD imaging library.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2011 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.image.adapter
+ * @category Community Framework
+ */
+class GDImageAdapter implements IImageAdapter {
+ /**
+ * active color
+ */
+ protected $color = null;
+
/**
* image height
* @var integer
protected $width = 0;
/**
- * Loads an image from a resource.
- *
- * @param resource $image
- * @param integer $type
+ * @see wcf\system\image\adapter\IImageAdapter::load()
*/
public function load($image, $type = '') {
if (!is_resource($image)) {
}
/**
- * Loads an image from file.
- *
- * @param string $file
+ * @see wcf\system\image\adapter\IImageAdapter::loadFile()
*/
public function loadFile($file) {
list($this->width, $this->height, $this->type) = getImageSize($file);
}
/**
- * Creates a thumbnail from previously loaded image.
- *
- * @param integer $maxWidth
- * @param integer $maxHeight
- * @param boolean $obtainDimensions
- * @return resource
+ * @see wcf\system\image\adapter\IImageAdapter::createThumbnail()
*/
public function createThumbnail($maxWidth, $maxHeight, $obtainDimensions = true) {
- if ($maxWidth > $this->width || $maxHeight > $this->height) {
- throw new SystemException("Dimensions for thumbnail can not exceed image dimensions.");
- }
-
$width = $height = $x = $y = 0;
if ($obtainDimensions) {
}
/**
- * Clips a part of currently loaded image, overwrites image resource within instance.
- *
- * @param integer $originX
- * @param integer $originY
- * @param integer $width
- * @param integer $height
- * @see wcf\system\image\adapter\GDImageAdapter::getImage()
+ * @see wcf\system\image\adapter\IImageAdapter::clip()
*/
public function clip($originX, $originY, $width, $height) {
- // validate if coordinates and size are within bounds
- if ($originX < 0 || $originY < 0) {
- throw new SystemException("Clipping an image requires valid offsets, an offset below zero is invalid.");
- }
- if ($width <= 0 || $height <= 0) {
- throw new SystemException("Clipping an image requires valid dimensions, width or height below or equal zero are invalid.");
- }
- if ((($originX + $width) > $this->width) || (($originY + $height) > $this->height)) {
- throw new SystemException("Offset and dimension can not exceed image dimensions.");
- }
-
$image = imageCreateTrueColor($width, $height);
imageAlphaBlending($image, false);
}
/**
- * Resizes an image with optional scaling, overwrites image resource within instance.
- *
- * @param integer $originX
- * @param integer $originY
- * @param integer $originWidth
- * @param integer $originHeight
- * @param integer $targetX
- * @param integer $targetY
- * @param integer $targetWidth
- * @param integer $targetHeight
- * @see wcf\system\image\adapter\GDImageAdapter::getImage()
+ * @see wcf\system\image\adapter\IImageAdapter::resize()
*/
public function resize($originX, $originY, $originWidth, $originHeight, $targetX = 0, $targetY = 0, $targetWidth = 0, $targetHeight = 0) {
- // use origin dimensions if target dimensions are both zero
- if ($targetWidth == 0 && $targetHeight == 0) {
- $targetWidth = $originWidth;
- $targetHeight = $originHeight;
- }
-
$image = imageCreateTrueColor($targetWidth, $targetHeight);
imageAlphaBlending($image, false);
}
/**
- * Draws a rectangle, overwrites image resource within instance.
- *
- * @param integer $startX
- * @param integer $startY
- * @param integer $endX
- * @param integer $endY
- * @param integer $color
- * @see wcf\system\image\adapter\GDImageAdapter::getColor()
- * @see wcf\system\image\adapter\GDImageAdapter::getImage()
+ * @see wcf\system\image\adapter\IImageAdapter::drawRectangle()
*/
- public function drawRectangle($startX, $startY, $endX, $endY, $color) {
- imageFilledRectangle($this->image, $startX, $startY, $endX, $endY, $color);
+ public function drawRectangle($startX, $startY, $endX, $endY) {
+ imageFilledRectangle($this->image, $startX, $startY, $endX, $endY, $this->color);
}
/**
- * Draws a line of text, overwrites image resource within instance.
- *
- * @param string $string
- * @param integer $x
- * @param integer $y
- * @param integer $color
- * @param integer $font
- * @see wcf\system\image\adapter\GDImageAdapter::getColor()
- * @see wcf\system\image\adapter\GDImageAdapter::getImage()
+ * @see wcf\system\image\adapter\IImageAdapter::drawText()
*/
- public function drawText($string, $x, $y, $color, $font = 3) {
- imageString($this->image, $font, $x, $y, $string, $color);
+ public function drawText($string, $x, $y) {
+ imageString($this->image, 3, $x, $y, $string, $this->color);
}
/**
- * Creates a color value based upon RGB.
- *
- * @param integer $red
- * @param integer $green
- * @param integer $blue
- * @return integer
+ * @see wcf\system\image\adapter\IImageAdapter::setColor()
*/
- public function getColor($red, $green, $blue) {
- return imageColorAllocate($this->image, $red, $green, $blue);
+ public function setColor($red, $green, $blue) {
+ $this->color = imageColorAllocate($this->image, $red, $green, $blue);
}
/**
- * Writes an image to disk.
- *
- * @param resource $image
- * @param string $filename
- */
+ * @see wcf\system\image\adapter\IImageAdapter::hasColor()
+ */
+ public function hasColor() {
+ return ($this->color !== null);
+ }
+
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::writeImage()
+ */
public function writeImage($image, $filename) {
ob_start();
- if ($this->type == IMAGETYPE_GIF && function_exists('imageGIF')) {
+ if ($this->type == IMAGETYPE_GIF) {
imageGIF($image);
}
- else if (($this->type == IMAGETYPE_GIF || $this->type == IMAGETYPE_PNG) && function_exists('imagePNG')) {
+ else if ($this->type == IMAGETYPE_PNG) {
imagePNG($image);
}
else if (function_exists('imageJPEG')) {
}
/**
- * Returns image resource.
- *
- * @return resource
+ * @see wcf\system\image\adapter\IImageAdapter::getImage()
*/
public function getImage() {
return $this->image;
+<?php
+namespace wcf\system\image\adapter;
+
+/**
+ * Basic interface for all image adapters.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2011 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.image.adapter
+ * @category Community Framework
+ */
+interface IImageAdapter {
+ /**
+ * Loads an image resource.
+ *
+ * @param mixed $image
+ * @param integer $type
+ */
+ public function load($image, $type = 0);
+
+ /**
+ * Loads an image from file.
+ *
+ * @param string $file
+ */
+ public function loadFile($file);
+
+ /**
+ * Creates a thumbnail from previously loaded image.
+ *
+ * @param integer $maxWidth
+ * @param integer $maxHeight
+ * @param boolean $obtainDimensions
+ * @return mixed
+ */
+ public function createThumbnail($maxWidth, $maxHeight, $obtainDimensions = true);
+
+ /**
+ * Clips a part of currently loaded image, overwrites image resource within instance.
+ *
+ * @param integer $originX
+ * @param integer $originY
+ * @param integer $width
+ * @param integer $height
+ * @see wcf\system\image\adapter\IImageAdapter::getImage()
+ */
+ public function clip($originX, $originY, $width, $height);
+
+ /**
+ * Resizes an image with optional scaling, overwrites image resource within instance.
+ *
+ * @param integer $originX
+ * @param integer $originY
+ * @param integer $originWidth
+ * @param integer $originHeight
+ * @param integer $targetX
+ * @param integer $targetY
+ * @param integer $targetWidth
+ * @param integer $targetHeight
+ * @see wcf\system\image\adapter\IImageAdapter::getImage()
+ */
+ public function resize($originX, $originY, $originWidth, $originHeight, $targetX, $targetY, $targetWidth, $targetHeight);
+
+ /**
+ * Draws a rectangle, overwrites image resource within instance.
+ *
+ * @param integer $startX
+ * @param integer $startY
+ * @param integer $endX
+ * @param integer $endY
+ * @see wcf\system\image\adapter\IImageAdapter::getImage()
+ * @see wcf\system\image\adapter\IImageAdapter::setColor()
+ */
+ public function drawRectangle($startX, $startY, $endX, $endY);
+
+ /**
+ * Draws a line of text, overwrites image resource within instance.
+ *
+ * @param string $string
+ * @param integer $x
+ * @param integer $y
+ * @see wcf\system\image\adapter\IImageAdapter::getImage()
+ * @see wcf\system\image\adapter\IImageAdapter::setColor()
+ */
+ public function drawText($string, $x, $y);
+
+ /**
+ * Sets active color.
+ *
+ * @param integer $red
+ * @param integer $green
+ * @param integer $blue
+ */
+ public function setColor($red, $green, $blue);
+
+ /**
+ * Returns true if a color has been set.
+ *
+ * @return boolean
+ */
+ public function hasColor();
+
+ /**
+ * Writes an image to disk.
+ *
+ * @param mixed $image
+ * @param string $filename
+ */
+ public function writeImage($image, $filename);
+
+ /**
+ * Returns image resource.
+ *
+ * @return mixed
+ */
+ public function getImage();
+
+ /**
+ * Returns image width.
+ *
+ * @return integer
+ */
+ public function getWidth();
+
+ /**
+ * Returns image height
+ *
+ * @return integer
+ */
+ public function getHeight();
+}
namespace wcf\system\image\adapter;
use wcf\system\session\SystemException;
-class ImageAdapter {
+/**
+ * Wrapper for image adapters.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2011 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.image.adapter
+ * @category Community Framework
+ */
+class ImageAdapter implements IImageAdapter {
+ /**
+ * IImageAdapter object
+ *
+ * @var IImageAdapter
+ */
protected $adapter = null;
+ /**
+ * Creates a new ImageAdapter instance.
+ *
+ * @param string $adapterClassName
+ */
public function __construct($adapterClassName) {
$this->adapter = new $adapterClassName();
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::load()
+ */
public function load($image, $type = 0) {
$this->adapter->load($image, $type);
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::loadFile()
+ */
public function loadFile($file) {
if (!file_exists($file) || !is_readable($file)) {
throw new SystemException("Image '".$file."' is not readable or does not exists.");
$this->adapter->loadFile($file);
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::createThumbnail()
+ */
public function createThumbnail($maxWidth, $maxHeight, $obtainDimensions = true) {
if ($maxWidth > $this->getWidth() || $maxHeight > $this->getHeight()) {
throw new SystemException("Dimensions for thumbnail can not exceed image dimensions.");
return $this->adapter->createThumbnail($maxWidth, $maxHeight, $obtainDimensions);
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::clip()
+ */
public function clip($originX, $originY, $width, $height) {
// validate if coordinates and size are within bounds
if ($originX < 0 || $originY < 0) {
$this->adapter->clip($originX, $originY, $width, $height);
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::resize()
+ */
public function resize($originX, $originY, $originWidth, $originHeight, $targetX, $targetY, $targetWidth, $targetHeight) {
// use origin dimensions if target dimensions are both zero
if ($targetWidth == 0 && $targetHeight == 0) {
$this->adapter->resize($originX, $originY, $originWidth, $originHeight, $targetX, $targetY, $targetWidth, $targetHeight);
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::drawRectangle()
+ */
public function drawRectangle($startX, $startY, $endX, $endY) {
if (!$this->adapter->hasColor()) {
throw new SystemException("Cannot draw a rectangle unless a color has been specified with setColor().");
$this->adapter->drawRectangle($startX, $startY, $endX, $endY);
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::drawText()
+ */
public function drawText($string, $x, $y) {
if (!$this->adapter->hasColor()) {
throw new SystemException("Cannot draw text unless a color has been specified with setColor().");
$this->adapter->drawText($string, $x, $y);
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::setColor()
+ */
public function setColor($red, $green, $blue) {
$this->adapter->setColor($red, $green, $blue);
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::hasColor()
+ */
+ public function hasColor() {
+ return $this->adapter->hasColor();
+ }
+
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::writeImage()
+ */
+ public function writeImage($image, $filename) {
+ $this->adapter->writeImage($image, $filename);
+ }
+
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::getImage()
+ */
+ public function getImage() {
+ return $this->adapter->getImage();
+ }
+
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::getWidth()
+ */
public function getWidth() {
return $this->adapter->getWidth();
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::getHeight()
+ */
public function getHeight() {
return $this->adapter->getHeight();
}
<?php
-require_once('GD.php');
+namespace wcf\system\image\adapter;
-class ImagickImageAdapter extends GDImageAdapter {
- protected $imagick = null;
+/**
+ * Image adapter for ImageMagick imaging library.
+ *
+ * @author Alexander Ebert
+ * @copyright 2001-2011 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.image.adapter
+ * @category Community Framework
+ */
+class ImagickImageAdapter implements IImageAdapter {
+ /**
+ * active color
+ *
+ * @var \ImagickPixel
+ */
protected $color = null;
+ /**
+ * Imagick object
+ *
+ * @var \Imagick
+ */
+ protected $imagick = null;
+
+ /**
+ * image height
+ * @var integer
+ */
+ protected $height = 0;
+ /**
+ * image width
+ * @var integer
+ */
+ protected $width = 0;
+
+ /**
+ * Creates a new ImagickImageAdapter.
+ */
public function __construct() {
$this->imagick = new \Imagick();
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::load()
+ */
public function load($image, $type = '') {
if (!($image instanceof \Imagick)) {
throw new SystemException("Object must be an instance of Imagick");
$this->width = $this->imagick->getImageWidth();
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::loadFile()
+ */
public function loadFile($file) {
try {
$this->imagick->readImage($file);
$this->width = $this->imagick->getImageWidth();
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::createThumbnail()
+ */
public function createThumbnail($maxWidth, $maxHeight, $obtainDimensions = true) {
$thumbnail = $this->imagick;
return $thumbnail;
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::clip()
+ */
public function clip($originX, $originY, $width, $height) {
- // validate if coordinates and size are within bounds
- if ($originX < 0 || $originY < 0) {
- throw new SystemException("Clipping an image requires valid offsets, an offset below zero is invalid.");
- }
- if ($width <= 0 || $height <= 0) {
- throw new SystemException("Clipping an image requires valid dimensions, width or height below or equal zero are invalid.");
- }
- if ((($originX + $width) > $this->width) || (($originY + $height) > $this->height)) {
- throw new SystemException("Offset and dimension can not exceed image dimensions.");
- }
-
$this->imagick->cropImage($width, $height, $originX, $originY);
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::drawRectangle()
+ */
public function drawRectangle($startX, $startY, $endX, $endY, $color) {
$draw = new \ImagickDraw();
$draw->setFillColor($this->color);
$this->imagick->drawImage($draw);
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::drawText()
+ */
public function drawText($string, $x, $y, $color, $font = 4) {
$draw = new \ImagickDraw();
$draw->setFillColor($this->color);
$this->imagick->drawImage($draw);
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::setColor()
+ */
public function setColor($red, $green, $blue) {
$this->color = new \ImagickPixel();
$this->color->setColor('rgb('.$red.','.$green.','.$blue.')');
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::hasColor()
+ */
public function hasColor() {
if ($this->color instanceof \ImagickPixel) {
return true;
return false;
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::getImage()
+ */
public function getImage() {
return $this->imagick;
}
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::writeImage()
+ */
public function writeImage($image, $filename) {
$image->writeImage($filename);
}
+
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::getHeight()
+ */
+ public function getHeight() {
+ return $this->height;
+ }
+
+ /**
+ * @see wcf\system\image\adapter\IImageAdapter::getWidth()
+ */
+ public function getWidth() {
+ return $this->width;
+ }
}