You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							255 lines
						
					
					
						
							7.9 KiB
						
					
					
				
			
		
		
	
	
							255 lines
						
					
					
						
							7.9 KiB
						
					
					
				<?php | 
						|
/** | 
						|
 * @link http://www.yiiframework.com/ | 
						|
 * @copyright Copyright (c) 2008 Yii Software LLC | 
						|
 * @license http://www.yiiframework.com/license/ | 
						|
 */ | 
						|
 | 
						|
namespace yii\imagine; | 
						|
 | 
						|
use Yii; | 
						|
use Imagine\Image\Box; | 
						|
use Imagine\Image\Color; | 
						|
use Imagine\Image\ImageInterface; | 
						|
use Imagine\Image\ImagineInterface; | 
						|
use Imagine\Image\ManipulatorInterface; | 
						|
use Imagine\Image\Point; | 
						|
use yii\base\InvalidConfigException; | 
						|
use yii\base\InvalidParamException; | 
						|
use yii\helpers\ArrayHelper; | 
						|
 | 
						|
/** | 
						|
 * BaseImage provides concrete implementation for [[Image]]. | 
						|
 * | 
						|
 * Do not use BaseImage. Use [[Image]] instead. | 
						|
 * | 
						|
 * @author Antonio Ramirez <amigo.cobos@gmail.com> | 
						|
 * @author Qiang Xue <qiang.xue@gmail.com> | 
						|
 * @since 2.0 | 
						|
 */ | 
						|
class BaseImage | 
						|
{ | 
						|
	/** | 
						|
	 * GD2 driver definition for Imagine implementation using the GD library. | 
						|
	 */ | 
						|
	const DRIVER_GD2 = 'gd2'; | 
						|
	/** | 
						|
	 * imagick driver definition. | 
						|
	 */ | 
						|
	const DRIVER_IMAGICK = 'imagick'; | 
						|
	/** | 
						|
	 * gmagick driver definition. | 
						|
	 */ | 
						|
	const DRIVER_GMAGICK = 'gmagick'; | 
						|
	/** | 
						|
	 * @var array|string the driver to use. This can be either a single driver name or an array of driver names. | 
						|
	 * If the latter, the first available driver will be used. | 
						|
	 */ | 
						|
	public static $driver = [self::DRIVER_GMAGICK, self::DRIVER_IMAGICK, self::DRIVER_GD2]; | 
						|
 | 
						|
	/** | 
						|
	 * @var ImagineInterface instance. | 
						|
	 */ | 
						|
	private static $_imagine; | 
						|
 | 
						|
	/** | 
						|
	 * Returns the `Imagine` object that supports various image manipulations. | 
						|
	 * @return ImagineInterface the `Imagine` object | 
						|
	 */ | 
						|
	public static function getImagine() | 
						|
	{ | 
						|
		if (self::$_imagine === null) { | 
						|
			self::$_imagine = static::createImagine(); | 
						|
		} | 
						|
		return self::$_imagine; | 
						|
	} | 
						|
 | 
						|
	/** | 
						|
	 * @param ImagineInterface $imagine the `Imagine` object. | 
						|
	 */ | 
						|
	public static function setImagine($imagine) | 
						|
	{ | 
						|
		self::$_imagine = $imagine; | 
						|
	} | 
						|
 | 
						|
	/** | 
						|
	 * Creates an `Imagine` object based on the specified [[driver]]. | 
						|
	 * @return ImagineInterface the new `Imagine` object | 
						|
	 * @throws InvalidConfigException if [[driver]] is unknown or the system doesn't support any [[driver]]. | 
						|
	 */ | 
						|
	protected static function createImagine() | 
						|
	{ | 
						|
		foreach ((array)static::$driver as $driver) { | 
						|
			switch ($driver) { | 
						|
				case self::DRIVER_GMAGICK: | 
						|
					if (class_exists('Gmagick', false)) { | 
						|
						return new \Imagine\Gmagick\Imagine(); | 
						|
					} | 
						|
					break; | 
						|
				case self::DRIVER_IMAGICK: | 
						|
					if (class_exists('Imagick', false)) { | 
						|
						return new \Imagine\Imagick\Imagine(); | 
						|
					} | 
						|
					break; | 
						|
				case self::DRIVER_GD2: | 
						|
					if (function_exists('gd_info')) { | 
						|
						return new \Imagine\Gd\Imagine(); | 
						|
					} | 
						|
					break; | 
						|
				default: | 
						|
					throw new InvalidConfigException("Unknown driver: $driver"); | 
						|
			} | 
						|
		} | 
						|
		throw new InvalidConfigException("Your system does not support any of these drivers: " . implode(',', (array)static::$driver)); | 
						|
	} | 
						|
 | 
						|
	/** | 
						|
	 * Crops an image. | 
						|
	 * | 
						|
	 * For example, | 
						|
	 * | 
						|
	 * ~~~ | 
						|
	 * $obj->crop('path\to\image.jpg', 200, 200, [5, 5]); | 
						|
	 * | 
						|
	 * $point = new \Imagine\Image\Point(5, 5); | 
						|
	 * $obj->crop('path\to\image.jpg', 200, 200, $point); | 
						|
	 * ~~~ | 
						|
	 * | 
						|
	 * @param string $filename the image file path or path alias. | 
						|
	 * @param integer $width the crop width | 
						|
	 * @param integer $height the crop height | 
						|
	 * @param array $start the starting point. This must be an array with two elements representing `x` and `y` coordinates. | 
						|
	 * @return ImageInterface | 
						|
	 * @throws InvalidParamException if the `$start` parameter is invalid | 
						|
	 */ | 
						|
	public static function crop($filename, $width, $height, array $start = [0, 0]) | 
						|
	{ | 
						|
		if (!isset($start[0], $start[1])) { | 
						|
			throw new InvalidParamException('$start must be an array of two elements.'); | 
						|
		} | 
						|
 | 
						|
		return static::getImagine() | 
						|
			->open(Yii::getAlias($filename)) | 
						|
			->copy() | 
						|
			->crop(new Point($start[0], $start[1]), new Box($width, $height)); | 
						|
	} | 
						|
 | 
						|
	/** | 
						|
	 * Creates a thumbnail image. The function differs from [[\Imagine\Image\ImageInterface::thumbnail()]] function that | 
						|
	 * it keeps the aspect ratio of the image. | 
						|
	 * @param string $filename the image file path or path alias. | 
						|
	 * @param integer $width the width in pixels to create the thumbnail | 
						|
	 * @param integer $height the height in pixels to create the thumbnail | 
						|
	 * @param string $mode | 
						|
	 * @return ImageInterface | 
						|
	 */ | 
						|
	public static function thumbnail($filename, $width, $height, $mode = ManipulatorInterface::THUMBNAIL_OUTBOUND) | 
						|
	{ | 
						|
		$box = new Box($width, $height); | 
						|
		$img = static::getImagine()->open(Yii::getAlias($filename)); | 
						|
 | 
						|
		if (($img->getSize()->getWidth() <= $box->getWidth() && $img->getSize()->getHeight() <= $box->getHeight()) || (!$box->getWidth() && !$box->getHeight())) { | 
						|
			return $img->copy(); | 
						|
		} | 
						|
 | 
						|
		$img = $img->thumbnail($box, $mode); | 
						|
 | 
						|
		// create empty image to preserve aspect ratio of thumbnail | 
						|
		$thumb = static::getImagine()->create($box); | 
						|
 | 
						|
		// calculate points | 
						|
		$size = $img->getSize(); | 
						|
 | 
						|
		$startX = 0; | 
						|
		$startY = 0; | 
						|
		if ($size->getWidth() < $width) { | 
						|
			$startX = ceil($width - $size->getWidth()) / 2; | 
						|
		} | 
						|
		if ($size->getHeight() < $height) { | 
						|
			$startY = ceil($height - $size->getHeight()) / 2; | 
						|
		} | 
						|
 | 
						|
		$thumb->paste($img, new Point($startX, $startY)); | 
						|
 | 
						|
		return $thumb; | 
						|
	} | 
						|
 | 
						|
	/** | 
						|
	 * Adds a watermark to an existing image. | 
						|
	 * @param string $filename the image file path or path alias. | 
						|
	 * @param string $watermarkFilename the file path or path alias of the watermark image. | 
						|
	 * @param array $start the starting point. This must be an array with two elements representing `x` and `y` coordinates. | 
						|
	 * @return ImageInterface | 
						|
	 * @throws InvalidParamException if `$start` is invalid | 
						|
	 */ | 
						|
	public static function watermark($filename, $watermarkFilename, array $start = [0, 0]) | 
						|
	{ | 
						|
		if (!isset($start[0], $start[1])) { | 
						|
			throw new InvalidParamException('$start must be an array of two elements.'); | 
						|
		} | 
						|
 | 
						|
		$img = static::getImagine()->open(Yii::getAlias($filename)); | 
						|
		$watermark = static::getImagine()->open(Yii::getAlias($watermarkFilename)); | 
						|
		$img->paste($watermark, new Point($start[0], $start[1])); | 
						|
		return $img; | 
						|
	} | 
						|
 | 
						|
	/** | 
						|
	 * Draws a text string on an existing image. | 
						|
	 * @param string $filename the image file path or path alias. | 
						|
	 * @param string $text the text to write to the image | 
						|
	 * @param string $fontFile the file path or path alias | 
						|
	 * @param array $start the starting position of the text. This must be an array with two elements representing `x` and `y` coordinates. | 
						|
	 * @param array $fontOptions the font options. The following options may be specified: | 
						|
	 * | 
						|
	 * - color: The font color. Defaults to "fff". | 
						|
	 * - size: The font size. Defaults to 12. | 
						|
	 * - angle: The angle to use to write the text. Defaults to 0. | 
						|
	 * | 
						|
	 * @return ImageInterface | 
						|
	 * @throws InvalidParamException if `$fontOptions` is invalid | 
						|
	 */ | 
						|
	public static function text($filename, $text, $fontFile, array $start = [0, 0], array $fontOptions = []) | 
						|
	{ | 
						|
		if (!isset($start[0], $start[1])) { | 
						|
			throw new InvalidParamException('$start must be an array of two elements.'); | 
						|
		} | 
						|
 | 
						|
		$fontSize = ArrayHelper::getValue($fontOptions, 'size', 12); | 
						|
		$fontColor = ArrayHelper::getValue($fontOptions, 'color', 'fff'); | 
						|
		$fontAngle = ArrayHelper::getValue($fontOptions, 'angle', 0); | 
						|
 | 
						|
		$img = static::getImagine()->open(Yii::getAlias($filename)); | 
						|
		$font = static::getImagine()->font(Yii::getAlias($fontFile), $fontSize, new Color($fontColor)); | 
						|
 | 
						|
		$img->draw()->text($text, $font, new Point($start[0], $start[1]), $fontAngle); | 
						|
 | 
						|
		return $img; | 
						|
	} | 
						|
 | 
						|
	/** | 
						|
	 * Adds a frame around of the image. Please note that the image size will increase by `$margin` x 2. | 
						|
	 * @param string $filename the full path to the image file | 
						|
	 * @param integer $margin the frame size to add around the image | 
						|
	 * @param string $color the frame color | 
						|
	 * @param integer $alpha the alpha value of the frame. | 
						|
	 * @return ImageInterface | 
						|
	 */ | 
						|
	public static function frame($filename, $margin = 20, $color = '666', $alpha = 100) | 
						|
	{ | 
						|
		$img = static::getImagine()->open(Yii::getAlias($filename)); | 
						|
 | 
						|
		$size = $img->getSize(); | 
						|
 | 
						|
		$pasteTo = new Point($margin, $margin); | 
						|
		$padColor = new Color($color, $alpha); | 
						|
 | 
						|
		$box = new Box($size->getWidth() + ceil($margin * 2), $size->getHeight() + ceil($margin * 2)); | 
						|
 | 
						|
		$image = static::getImagine()->create($box, $padColor); | 
						|
 | 
						|
		$image->paste($img, $pasteTo); | 
						|
 | 
						|
		return $image; | 
						|
	} | 
						|
}
 | 
						|
 |