From: Alexander Ebert Date: Tue, 26 Jul 2011 16:06:58 +0000 (+0200) Subject: Implemented image adapters for GD and ImageMagick X-Git-Tag: 2.0.0_Beta_1~1946 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=64a820cfb6e9f2b84bd4c7f0838222e5d67e9531;p=GitHub%2FWoltLab%2FWCF.git Implemented image adapters for GD and ImageMagick 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. --- diff --git a/wcfsetup/install/files/lib/system/image/adapter/GDImageAdapter.class.php b/wcfsetup/install/files/lib/system/image/adapter/GDImageAdapter.class.php index 775901234b..64e077205c 100644 --- a/wcfsetup/install/files/lib/system/image/adapter/GDImageAdapter.class.php +++ b/wcfsetup/install/files/lib/system/image/adapter/GDImageAdapter.class.php @@ -1,5 +1,22 @@ + * @package com.woltlab.wcf + * @subpackage system.image.adapter + * @category Community Framework + */ +class GDImageAdapter implements IImageAdapter { + /** + * active color + */ + protected $color = null; + /** * image height * @var integer @@ -25,10 +42,7 @@ class GDImageAdapter { 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)) { @@ -47,9 +61,7 @@ class GDImageAdapter { } /** - * 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); @@ -74,18 +86,9 @@ class GDImageAdapter { } /** - * 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) { @@ -122,26 +125,9 @@ class GDImageAdapter { } /** - * 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); @@ -152,25 +138,9 @@ class GDImageAdapter { } /** - * 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); @@ -181,60 +151,43 @@ class GDImageAdapter { } /** - * 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')) { @@ -248,9 +201,7 @@ class GDImageAdapter { } /** - * Returns image resource. - * - * @return resource + * @see wcf\system\image\adapter\IImageAdapter::getImage() */ public function getImage() { return $this->image; diff --git a/wcfsetup/install/files/lib/system/image/adapter/IImageAdapter.class.php b/wcfsetup/install/files/lib/system/image/adapter/IImageAdapter.class.php index e69de29bb2..fcf235a489 100644 --- a/wcfsetup/install/files/lib/system/image/adapter/IImageAdapter.class.php +++ b/wcfsetup/install/files/lib/system/image/adapter/IImageAdapter.class.php @@ -0,0 +1,133 @@ + + * @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(); +} diff --git a/wcfsetup/install/files/lib/system/image/adapter/ImageAdapter.class.php b/wcfsetup/install/files/lib/system/image/adapter/ImageAdapter.class.php index 47c1bf1848..b2173f6ab8 100644 --- a/wcfsetup/install/files/lib/system/image/adapter/ImageAdapter.class.php +++ b/wcfsetup/install/files/lib/system/image/adapter/ImageAdapter.class.php @@ -2,17 +2,43 @@ 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 + * @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."); @@ -21,6 +47,9 @@ class ImageAdapter { $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."); @@ -29,6 +58,9 @@ class ImageAdapter { 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) { @@ -44,6 +76,9 @@ class ImageAdapter { $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) { @@ -54,6 +89,9 @@ class ImageAdapter { $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()."); @@ -62,6 +100,9 @@ class ImageAdapter { $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()."); @@ -70,14 +111,44 @@ class ImageAdapter { $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(); } diff --git a/wcfsetup/install/files/lib/system/image/adapter/ImagickImageAdapter.class.php b/wcfsetup/install/files/lib/system/image/adapter/ImagickImageAdapter.class.php index 497a299a64..2398ad349f 100644 --- a/wcfsetup/install/files/lib/system/image/adapter/ImagickImageAdapter.class.php +++ b/wcfsetup/install/files/lib/system/image/adapter/ImagickImageAdapter.class.php @@ -1,15 +1,53 @@ + * @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"); @@ -20,6 +58,9 @@ class ImagickImageAdapter extends GDImageAdapter { $this->width = $this->imagick->getImageWidth(); } + /** + * @see wcf\system\image\adapter\IImageAdapter::loadFile() + */ public function loadFile($file) { try { $this->imagick->readImage($file); @@ -31,6 +72,9 @@ class ImagickImageAdapter extends GDImageAdapter { $this->width = $this->imagick->getImageWidth(); } + /** + * @see wcf\system\image\adapter\IImageAdapter::createThumbnail() + */ public function createThumbnail($maxWidth, $maxHeight, $obtainDimensions = true) { $thumbnail = $this->imagick; @@ -40,21 +84,16 @@ class ImagickImageAdapter extends GDImageAdapter { 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); @@ -64,6 +103,9 @@ class ImagickImageAdapter extends GDImageAdapter { $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); @@ -74,12 +116,18 @@ class ImagickImageAdapter extends GDImageAdapter { $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; @@ -88,11 +136,31 @@ class ImagickImageAdapter extends GDImageAdapter { 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; + } }