PageRenderTime 24ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/protected/modules/yupe/components/image/Imagine.php

https://gitlab.com/RonLab1987/YupePlusClear
PHP | 283 lines | 143 code | 40 blank | 100 comment | 18 complexity | 56b93e4f5ed81459788e17f2fd6d11a4 MD5 | raw file
  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yupe\components\image;
  8. use Imagine\Image\Palette\RGB;
  9. use Yii;
  10. use Imagine\Image\Box;
  11. use Imagine\Image\ImageInterface;
  12. use Imagine\Image\ImagineInterface;
  13. use Imagine\Image\ManipulatorInterface;
  14. use Imagine\Image\Point;
  15. /**
  16. * Ported Yii 2 imagine wrapper for Yii 1
  17. *
  18. * @author Antonio Ramirez <amigo.cobos@gmail.com>
  19. * @author Qiang Xue <qiang.xue@gmail.com>
  20. */
  21. class Imagine
  22. {
  23. /**
  24. * GD2 driver definition for Imagine implementation using the GD library.
  25. */
  26. const DRIVER_GD2 = 'gd2';
  27. /**
  28. * imagick driver definition.
  29. */
  30. const DRIVER_IMAGICK = 'imagick';
  31. /**
  32. * gmagick driver definition.
  33. */
  34. const DRIVER_GMAGICK = 'gmagick';
  35. /**
  36. * @var array|string the driver to use. This can be either a single driver name or an array of driver names.
  37. * If the latter, the first available driver will be used.
  38. */
  39. public static $driver = [self::DRIVER_GMAGICK, self::DRIVER_IMAGICK, self::DRIVER_GD2];
  40. /**
  41. * @var ImagineInterface instance.
  42. */
  43. private static $_imagine;
  44. /**
  45. * Returns the `Imagine` object that supports various image manipulations.
  46. * @return ImagineInterface the `Imagine` object
  47. */
  48. public static function getImagine()
  49. {
  50. if (self::$_imagine === null) {
  51. self::$_imagine = static::createImagine();
  52. }
  53. return self::$_imagine;
  54. }
  55. /**
  56. * @param ImagineInterface $imagine the `Imagine` object.
  57. */
  58. public static function setImagine($imagine)
  59. {
  60. self::$_imagine = $imagine;
  61. }
  62. /**
  63. * Creates an `Imagine` object based on the specified [[driver]].
  64. * @return ImagineInterface the new `Imagine` object
  65. * @throws \CException if [[driver]] is unknown or the system doesn't support any [[driver]].
  66. */
  67. protected static function createImagine()
  68. {
  69. foreach ((array)static::$driver as $driver) {
  70. switch ($driver) {
  71. case self::DRIVER_GMAGICK:
  72. if (class_exists('Gmagick', false)) {
  73. return new \Imagine\Gmagick\Imagine();
  74. }
  75. break;
  76. case self::DRIVER_IMAGICK:
  77. if (class_exists('Imagick', false)) {
  78. return new \Imagine\Imagick\Imagine();
  79. }
  80. break;
  81. case self::DRIVER_GD2:
  82. if (function_exists('gd_info')) {
  83. return new \Imagine\Gd\Imagine();
  84. }
  85. break;
  86. default:
  87. throw new \CException("Unknown driver: $driver");
  88. }
  89. }
  90. throw new \CException(
  91. "Your system does not support any of these drivers: " . implode(
  92. ',',
  93. (array)static::$driver
  94. )
  95. );
  96. }
  97. /**
  98. * Crops an image.
  99. *
  100. * For example,
  101. *
  102. * ~~~
  103. * $obj->crop('path\to\image.jpg', 200, 200, [5, 5]);
  104. *
  105. * $point = new \Imagine\Image\Point(5, 5);
  106. * $obj->crop('path\to\image.jpg', 200, 200, $point);
  107. * ~~~
  108. *
  109. * @param string $filename the image file path or path alias.
  110. * @param integer $width the crop width
  111. * @param integer $height the crop height
  112. * @param array $start the starting point. This must be an array with two elements representing `x` and `y` coordinates.
  113. * @return ImageInterface
  114. * @throws \CException if the `$start` parameter is invalid
  115. */
  116. public static function crop($filename, $width, $height, array $start = [0, 0])
  117. {
  118. if (!isset($start[0], $start[1])) {
  119. throw new \CException('$start must be an array of two elements.');
  120. }
  121. return static::getImagine()
  122. ->open($filename)
  123. ->copy()
  124. ->crop(new Point($start[0], $start[1]), new Box($width, $height));
  125. }
  126. /**
  127. * Creates a thumbnail image. The function differs from [[\Imagine\Image\ImageInterface::thumbnail()]] function that
  128. * it keeps the aspect ratio of the image.
  129. * @param string $filename the image file path or path alias.
  130. * @param integer $width the width in pixels to create the thumbnail
  131. * @param integer $height the height in pixels to create the thumbnail
  132. * @param string $mode
  133. * @return ImageInterface
  134. */
  135. public static function thumbnail($filename, $width, $height, $mode = ManipulatorInterface::THUMBNAIL_OUTBOUND)
  136. {
  137. $box = new Box($width, $height);
  138. $img = static::getImagine()->open($filename);
  139. if (($img->getSize()->getWidth() <= $box->getWidth() && $img->getSize()->getHeight() <= $box->getHeight()) ||
  140. (!$box->getWidth() && !$box->getHeight())
  141. ) {
  142. return $img->copy();
  143. }
  144. $img = $img->thumbnail($box, $mode);
  145. // create empty image to preserve aspect ratio of thumbnail
  146. $thumb = static::getImagine()->create($box, (new RGB())->color('FFF', 100));
  147. // calculate points
  148. $size = $img->getSize();
  149. $startX = 0;
  150. $startY = 0;
  151. if ($size->getWidth() < $width) {
  152. $startX = ceil($width - $size->getWidth()) / 2;
  153. }
  154. if ($size->getHeight() < $height) {
  155. $startY = ceil($height - $size->getHeight()) / 2;
  156. }
  157. $thumb->paste($img, new Point($startX, $startY));
  158. return $thumb;
  159. }
  160. /**
  161. * Adds a watermark to an existing image.
  162. * @param string $filename the image file path or path alias.
  163. * @param string $watermarkFilename the file path or path alias of the watermark image.
  164. * @param array $start the starting point. This must be an array with two elements representing `x` and `y` coordinates.
  165. * @return ImageInterface
  166. * @throws \CException if `$start` is invalid
  167. */
  168. public static function watermark($filename, $watermarkFilename, array $start = [0, 0])
  169. {
  170. if (!isset($start[0], $start[1])) {
  171. throw new \CException('$start must be an array of two elements.');
  172. }
  173. $img = static::getImagine()->open($filename);
  174. $watermark = static::getImagine()->open($watermarkFilename);
  175. $img->paste($watermark, new Point($start[0], $start[1]));
  176. return $img;
  177. }
  178. /**
  179. * Draws a text string on an existing image.
  180. * @param string $filename the image file path or path alias.
  181. * @param string $text the text to write to the image
  182. * @param string $fontFile the file path or path alias
  183. * @param array $start the starting position of the text. This must be an array with two elements representing `x` and `y` coordinates.
  184. * @param array $fontOptions the font options. The following options may be specified:
  185. *
  186. * - color: The font color. Defaults to "fff".
  187. * - size: The font size. Defaults to 12.
  188. * - angle: The angle to use to write the text. Defaults to 0.
  189. *
  190. * @return ImageInterface
  191. * @throws \CException if `$fontOptions` is invalid
  192. */
  193. public static function text($filename, $text, $fontFile, array $start = [0, 0], array $fontOptions = [])
  194. {
  195. if (!isset($start[0], $start[1])) {
  196. throw new \CException('$start must be an array of two elements.');
  197. }
  198. if (!isset($fontOptions['size'], $fontOptions['color'], $fontOptions['angle'])) {
  199. throw new \CException('$fontOptions must contain size, color and angle keys.');
  200. }
  201. $fontSize = $fontOptions['size'];
  202. $fontColor = $fontOptions['color'];
  203. $fontAngle = $fontOptions['angle'];
  204. $img = static::getImagine()->open($filename);
  205. $font = static::getImagine()->font($fontFile, $fontSize, (new RGB())->color($fontColor));
  206. $img->draw()->text($text, $font, new Point($start[0], $start[1]), $fontAngle);
  207. return $img;
  208. }
  209. /**
  210. * Adds a frame around of the image. Please note that the image size will increase by `$margin` x 2.
  211. * @param string $filename the full path to the image file
  212. * @param integer $margin the frame size to add around the image
  213. * @param string $color the frame color
  214. * @param integer $alpha the alpha value of the frame.
  215. * @return ImageInterface
  216. */
  217. public static function frame($filename, $margin = 20, $color = '666', $alpha = 100)
  218. {
  219. $img = static::getImagine()->open($filename);
  220. $size = $img->getSize();
  221. $pasteTo = new Point($margin, $margin);
  222. $box = new Box($size->getWidth() + ceil($margin * 2), $size->getHeight() + ceil($margin * 2));
  223. $image = static::getImagine()->create($box, (new RGB())->color($color, $alpha));
  224. $image->paste($img, $pasteTo);
  225. return $image;
  226. }
  227. public static function resize($filename, $width, $height)
  228. {
  229. $image = static::getImagine()->open($filename);
  230. $realWidth = $image->getSize()->getWidth();
  231. $realHeight = $image->getSize()->getHeight();
  232. if ($realWidth > $width || $realHeight > $height) {
  233. $ratio = $realWidth / $realHeight;
  234. if ($ratio > 1) {
  235. $height = $width / $ratio;
  236. } else {
  237. $width = $height * $ratio;
  238. }
  239. $image->resize(new \Imagine\Image\Box($width, $height));
  240. }
  241. return $image;
  242. }
  243. }