/ManaPHP/Image/Adapter/Gd.php

https://gitlab.com/szlongshu/manaphp · PHP · 268 lines · 156 code · 31 blank · 81 comment · 19 complexity · 1082818a6ce46c7c6cdbca279ece9231 MD5 · raw file

  1. <?php
  2. namespace ManaPHP\Image\Adapter {
  3. use ManaPHP\Image\AdapterInterface;
  4. class Gd implements AdapterInterface
  5. {
  6. /**
  7. * @var string
  8. */
  9. protected $_file;
  10. /**
  11. * @var string
  12. */
  13. protected $_real_path;
  14. /**
  15. * @var resource
  16. */
  17. protected $_image;
  18. /**
  19. * @var
  20. */
  21. protected $_width;
  22. /**
  23. * @var
  24. */
  25. protected $_height;
  26. /**
  27. * @param string $file
  28. *
  29. * @throws \ManaPHP\Image\Adapter\Exception
  30. */
  31. public function __construct($file)
  32. {
  33. if (!extension_loaded('gd')) {
  34. throw new Exception('gd is not installed, or the extension is not loaded');
  35. }
  36. if (is_file($file)) {
  37. $this->_file = $file;
  38. $this->_real_path = realpath($this->_file);
  39. $imageInfo = getimagesize($this->_real_path);
  40. list($this->_width, $this->_height, $type) = $imageInfo;
  41. if ($type === IMAGETYPE_GIF) {
  42. $this->_image = imagecreatefromgif($this->_real_path);
  43. } elseif ($type === IMAGETYPE_JPEG) {
  44. $this->_image = imagecreatefromjpeg($this->_real_path);
  45. } elseif ($type === IMAGETYPE_PNG) {
  46. $this->_image = imagecreatefrompng($this->_real_path);
  47. } else {
  48. throw new Exception('Installed GD does not support such images');
  49. }
  50. imagesavealpha($this->_image, true);
  51. } else {
  52. throw new Exception('the file is not exist: ' . $file);
  53. }
  54. }
  55. /**
  56. * Image width
  57. *
  58. * @return int
  59. */
  60. public function getWidth()
  61. {
  62. return $this->_width;
  63. }
  64. /**
  65. * Image height
  66. *
  67. * @return int
  68. */
  69. public function getHeight()
  70. {
  71. return $this->_height;
  72. }
  73. public function getInternalHandle()
  74. {
  75. return $this->_image;
  76. }
  77. /**
  78. * @param int $width
  79. * @param int $height
  80. *
  81. * @return static
  82. */
  83. public function resize($width, $height)
  84. {
  85. if (version_compare(PHP_VERSION, '5.5.0') < 0) {
  86. $image = imagecreatetruecolor($width, $height);
  87. imagealphablending($image, false);
  88. imagesavealpha($image, true);
  89. imagecopyresampled($image, $this->_image, 0, 0, 0, 0, $width, $height, $this->_width, $this->_height);
  90. } else {
  91. $image = imagescale($this->_image, $width, $height);
  92. }
  93. imagedestroy($this->_image);
  94. $this->_image = $image;
  95. $this->_width = imagesx($image);
  96. $this->_height = imagesy($image);
  97. return $this;
  98. }
  99. /**
  100. * Rotate the image by a given degrees
  101. *
  102. * @param int $degrees
  103. * @param int $background
  104. * @param float $alpha
  105. *
  106. * @return static
  107. */
  108. public function rotate($degrees, $background = 0xffffff, $alpha = 1.0)
  109. {
  110. $transparent = imagecolorallocatealpha($this->_image, ($background >> 16) & 0xFF, ($background >> 8) & 0xFF,
  111. $background & 0xFF, $alpha * 127);
  112. $image = imagerotate($this->_image, 360 - $degrees, $transparent, true);
  113. imagealphablending($image, false);
  114. imagesavealpha($image, true);
  115. imagedestroy($this->_image);
  116. $this->_image = $image;
  117. $this->_width = imagesx($image);
  118. $this->_height = imagesy($image);
  119. return $this;
  120. }
  121. /**
  122. * @param int $width
  123. * @param int $height
  124. * @param int $offsetX
  125. * @param int $offsetY
  126. *
  127. * @return static
  128. */
  129. public function crop($width, $height, $offsetX = 0, $offsetY = 0)
  130. {
  131. if (version_compare(PHP_VERSION, '5.5.0') < 0) {
  132. $image = imagecreatetruecolor($width, $height);
  133. imagealphablending($image, false);
  134. imagesavealpha($image, true);
  135. imagecopy($image, $this->_image, 0, 0, $offsetX, $offsetY, $width, $height);
  136. } else {
  137. $image = imagecrop($this->_image,
  138. ['x' => $offsetX, 'y' => $offsetY, 'width' => $width, 'height' => $height]);
  139. }
  140. imagedestroy($this->_image);
  141. $this->_image = $image;
  142. $this->_width = imagesx($image);
  143. $this->_height = imagesy($image);
  144. return $this;
  145. }
  146. /**
  147. * Execute a text
  148. *
  149. * @param string $text
  150. * @param int $offsetX
  151. * @param int $offsetY
  152. * @param float $opacity
  153. * @param int $color
  154. * @param int $size
  155. * @param string $font_file
  156. *
  157. * @return static
  158. */
  159. public function text(
  160. $text,
  161. $offsetX = 0,
  162. $offsetY = 0,
  163. $opacity = 1.0,
  164. $color = 0x000000,
  165. $size = 12,
  166. $font_file = null
  167. ) {
  168. $textColor = imagecolorallocatealpha($this->_image, ($color >> 16) & 0xFF, ($color >> 8) & 0xFF,
  169. $color & 0xFF, abs(1 - $opacity) * 127);
  170. if ($font_file !== null) {
  171. imagettftext($this->_image, $size, 0, $offsetX, $offsetY, $textColor, $font_file, $text);
  172. } else {
  173. imagestring($this->_image, $size, $offsetX, $offsetY, $text, $textColor);
  174. }
  175. return $this;
  176. }
  177. /**
  178. * @param string $file
  179. * @param int $offsetX
  180. * @param int $offsetY
  181. * @param float $opacity
  182. *
  183. * @return static
  184. * @throws \ManaPHP\Image\Adapter\Exception
  185. */
  186. public function watermark($file, $offsetX = 0, $offsetY = 0, $opacity = 1.0)
  187. {
  188. $maskImageInfo = getimagesize($file);
  189. list($maskWidth, $maskHeight, $maskType) = $maskImageInfo;
  190. if ($maskType === IMAGETYPE_GIF) {
  191. $maskImage = imagecreatefromgif($file);
  192. } elseif ($maskType === IMAGETYPE_JPEG) {
  193. $maskImage = imagecreatefromjpeg($file);
  194. } elseif ($maskType === IMAGETYPE_PNG) {
  195. $maskImage = imagecreatefrompng($file);
  196. } else {
  197. throw new Exception('Installed GD does not support such images');
  198. }
  199. imagesavealpha($maskImage, true);
  200. $image = imagecreatetruecolor($this->_width, $this->_height);
  201. imagealphablending($image, false);
  202. imagesavealpha($image, true);
  203. if ($maskType !== IMAGETYPE_PNG) {
  204. $filedColor = imagecolorallocatealpha($image, 127, 127, 127, (1 - $opacity) * 127);
  205. } else {
  206. $filedColor = imagecolorallocate($image, 127, 127, 127);
  207. }
  208. imagelayereffect($maskImage, IMG_EFFECT_OVERLAY);
  209. imagefilledrectangle($maskImage, 0, 0, $maskWidth, $maskHeight, $filedColor);
  210. imagealphablending($this->_image, true);
  211. imagecopy($this->_image, $maskImage, $offsetX, $offsetY, 0, 0, $maskWidth, $maskHeight);
  212. return $this;
  213. }
  214. /**
  215. * @param string $file
  216. * @param int $quality
  217. *
  218. * @throws \ManaPHP\Image\Adapter\Exception
  219. */
  220. public function save($file = null, $quality = 80)
  221. {
  222. $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
  223. if ($ext === '') {
  224. $ext = 'jpg';
  225. }
  226. if ($ext === 'gif') {
  227. imagegif($this->_image, $file);
  228. } elseif ($ext === 'jpg' || $ext === 'jpeg') {
  229. imagejpeg($this->_image, $file, $quality);
  230. } elseif ($ext === 'png') {
  231. imagepng($this->_image, $file);
  232. } else {
  233. throw new Exception("Installed GD does not support ' $ext ' images");
  234. }
  235. }
  236. }
  237. }