Mg.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. <?php namespace Image\Lib\Tool;
  2. use Dever;
  3. class Mg extends Core
  4. {
  5. private $imageType = false;
  6. private function imageType()
  7. {
  8. if (!$this->imageType) {
  9. $this->imageType = strtolower($this->im->getImageFormat());
  10. }
  11. }
  12. # 缩放
  13. public function thumb($set)
  14. {
  15. if (!$this->im) {
  16. return false;
  17. }
  18. $this->imageType();
  19. if (!is_array($set)) {
  20. $set = explode(',', $set);
  21. }
  22. $source_x = $this->im->getImageWidth();
  23. $source_y = $this->im->getImageHeight();
  24. $source_w = $source_x/$source_y;
  25. $source_h = $source_y/$source_x;
  26. foreach ($set as $k => $v) {
  27. $result[$k] = $this->getDest($v . '_thumb');
  28. if ($this->check($result[$k])) {
  29. list($dest_x, $dest_y, $offset) = $this->getXy($v, $source_x, $source_y, $source_w, $source_h);
  30. //$this->im = $this->get($this->source);
  31. $this->im->thumbnailImage($dest_x, $dest_y);
  32. if (isset($offset[2]) && $offset[2] == 3) {
  33. /* 按照缩略图大小创建一个有颜色的图片 */
  34. $canvas = $this->get();
  35. $color = new \ImagickPixel("white");
  36. $canvas->newImage($offset[0], $offset[1], $color, 'png');
  37. //$canvas->paintfloodfillimage('transparent',2000,NULL,0,0);
  38. /* 计算高度 */
  39. $x = ($offset[0] - $dest_x)/2;
  40. $y = ($offset[1] - $dest_y)/2;
  41. /* 合并图片 */
  42. $canvas->compositeImage($this->im, \Imagick::COMPOSITE_OVER, $x, $y);
  43. $canvas->setCompression(\Imagick::COMPRESSION_JPEG);
  44. $canvas->setCompressionQuality(100);
  45. $canvas->writeImage($result[$k]);
  46. if (isset($offset[3]) && $offset[3]) {
  47. $offset[3] = $offset[3] * 1024;
  48. $size = abs(filesize($result[$k]));
  49. if ($size > $offset[3]) {
  50. $this->compress($canvas, $offset[3], 80, $result[$k]);
  51. }
  52. }
  53. $canvas = false;
  54. } else {
  55. //$this->im->setCompression(\Imagick::COMPRESSION_JPEG);
  56. $this->im->setCompressionQuality(90);
  57. if ($this->imageType == 'gif') {
  58. $this->im->writeImages($result[$k], true);
  59. } else {
  60. $this->im->writeImage($result[$k]);
  61. }
  62. }
  63. }
  64. }
  65. return $result;
  66. }
  67. public function crop($set, $position)
  68. {
  69. if (!$this->im) {
  70. return false;
  71. }
  72. $this->imageType();
  73. $result = array();
  74. if (!is_array($set)) {
  75. $set = explode(',', $set);
  76. }
  77. $source_x = $this->im->getImageWidth();
  78. $source_y = $this->im->getImageHeight();
  79. foreach ($set as $k => $v) {
  80. $result[$k] = $this->getDest($v . '_crop');
  81. if ($this->check($result[$k])) {
  82. $offset = explode('_', $v);
  83. if (isset($offset[2]) && $offset[2]) {
  84. $offset[0] += $offset[2];
  85. $offset[1] += $offset[2];
  86. }
  87. if ($position) {
  88. if (!is_array($position)) {
  89. list($x, $y) = $this->position($source_x, $source_y, $offset[0], $offset[1], $position);
  90. } else {
  91. # 加入根据百分比计算裁图
  92. if ($position[0] <= 0) {
  93. $position[0] = $source_x/2 - $offset[0]/2;
  94. } elseif (strstr($position[0], '%')) {
  95. $position[0] = $source_x * intval(str_replace('%', '', $position[0]))/100;
  96. }
  97. if ($position[1] <= 0) {
  98. $position[1] = $source_y/2 - $offset[1]/2;
  99. } elseif (strstr($position[1], '%')) {
  100. $position[1] = $source_y * intval(str_replace('%', '', $position[1]))/100;
  101. }
  102. $x = $position[0];
  103. $y = $position[1];
  104. }
  105. } else {
  106. $x = $source_x/2 - $offset[0]/2;
  107. $y = $source_y/2 - $offset[1]/2;
  108. }
  109. if ($x < 0) {
  110. $x = 0;
  111. }
  112. if ($y < 0) {
  113. $y = 0;
  114. }
  115. if ($this->imageType == 'gif') {
  116. $this->gif($offset[0], $offset[1], $x, $y);
  117. } else {
  118. $this->im->cropImage($offset[0], $offset[1], $x, $y);
  119. }
  120. if (isset($offset[2]) && $offset[2] == 3 && isset($offset[3]) && $offset[3] > 0) {
  121. $this->im->writeImage($result[$k]);
  122. $offset[3] = $offset[3] * 1024;
  123. $size = abs(filesize($result[$k]));
  124. if ($size > $offset[3]) {
  125. $this->_compress($this->im, $offset[3], 80, $result[$k]);
  126. }
  127. } else {
  128. //$this->im->setCompression(\Imagick::COMPRESSION_JPEG);
  129. $this->im->setCompressionQuality(90);
  130. if ($this->imageType == 'gif') {
  131. $this->im->writeImages($result[$k], true);
  132. } else {
  133. $this->im->writeImage($result[$k]);
  134. }
  135. }
  136. }
  137. }
  138. return $result;
  139. }
  140. public function pic($water, $position = 5, $offset = 0, $width = 0, $height = 0, $radius = 0)
  141. {
  142. if (!$this->im) {
  143. return false;
  144. }
  145. $this->imageType();
  146. $result = $this->getDest('mark');
  147. if ($this->check($result)) {
  148. if ($radius) {
  149. $water = $this->get_radius($water, $radius);
  150. } else {
  151. $water = $this->get($water);
  152. }
  153. $draw = new \ImagickDraw();
  154. $source_x = $this->im->getImageWidth();
  155. $source_y = $this->im->getImageHeight();
  156. $water_x = $water->getImageWidth();
  157. $water_y = $water->getImageHeight();
  158. if ($width || $height) {
  159. $water_w = $water_x/$water_y;
  160. $water_h = $water_y/$water_x;
  161. if ($water_x > $width) {
  162. $dest_x = $width;
  163. $dest_y = $width*$water_h;
  164. } elseif ($height > 0 && $water_y > $height) {
  165. $dest_x = $height*$water_w;
  166. $dest_y = $height;
  167. } else {
  168. $dest_x = $water_x;
  169. $dest_y = $water_y;
  170. }
  171. //$water->thumbnailImage($dest_x, $dest_y);
  172. list($x, $y) = $this->position($water_x, $water_y, $width, $height, 5, 0);
  173. $water->cropImage($width, $height, $x, $y);
  174. $xy = $this->position($source_x, $source_y, $dest_x, $dest_y, $position, $offset);
  175. $water_x = $dest_x;
  176. $water_y = $dest_y;
  177. } else {
  178. $xy = $this->position($source_x, $source_y, $water_x, $water_y, $position, $offset);
  179. }
  180. if ($xy[0] == -1) {
  181. # 水印平铺
  182. $image = new \Imagick();
  183. $image->newImage($source_x, $source_y, new \ImagickPixel('none'));
  184. $image->setImageFormat('jpg');
  185. $water = $image->textureImage($water);
  186. $width = $source_x;
  187. $height = $source_y;
  188. $xy[0] = $xy[1] = 0;
  189. }
  190. if ($xy[2] == false) {
  191. $this->destroy($water);
  192. return;
  193. }
  194. $draw->composite($water->getImageCompose(), $xy[0], $xy[1], $width, $height, $water);
  195. if ($this->imageType == 'gif') {
  196. $this->gif(0, 0, 0, 0, $draw);
  197. } else {
  198. $this->im->drawImage($draw);
  199. }
  200. $this->im->writeImage($result);
  201. }
  202. return $result;
  203. }
  204. # 文字水印
  205. public function txt($name, $position = 5, $offset = 0, $size = 10, $color = '', $angle = 0, $width = 0, $font = 'SIMSUN.TTC')
  206. {
  207. if (!$this->im) {
  208. return false;
  209. }
  210. $this->imageType();
  211. $result = $this->getDest('txt');
  212. if ($this->check($result)) {
  213. $autowrap = 0;
  214. if ($width > 0) {
  215. $name = $this->autowrap($autowrap, $size, $angle, $font, $name, $width);
  216. }
  217. $draw = new \ImagickDraw();
  218. $draw->setFont($font);
  219. $position = imagettfbbox($size, $angle, $font, $name);
  220. if ($position) {
  221. $source_x = $this->im->getImageWidth();
  222. $source_y = $this->im->getImageHeight();
  223. $water_x = $position[2] - $position[0];
  224. $water_y = $position[1] - $position[7];
  225. $xy = $this->position($source_x, $source_y, $water_x, $water_y, $position, $offset);
  226. }
  227. if ($size) {
  228. $draw->setFontSize($size);
  229. }
  230. if ($color) {
  231. $draw->setFillColor($color);
  232. }
  233. /*
  234. if ($bgcolor) {
  235. $draw->setTextUnderColor($bgcolor);
  236. }*/
  237. $left = $xy[0] ?? 0;
  238. $top = $xy[1] ?? 0;
  239. $draw->setGravity(\Imagick::GRAVITY_NORTHWEST);
  240. if ($this->imageType == 'gif') {
  241. foreach ($this->im as $frame) {
  242. $frame->annotateImage($draw, $left, $top, $angle, $name);
  243. }
  244. } else {
  245. $this->im->annotateImage($draw, $left, $top + $autowrap, $angle, $name);
  246. }
  247. $this->_image->writeImage($result);
  248. }
  249. return $result;
  250. }
  251. protected function gif($w, $h, $x, $y, $d = false, $num = false)
  252. {
  253. $canvas = $this->get();
  254. $canvas->setFormat("gif");
  255. $this->im->coalesceImages();
  256. $num = $num ? $num : $this->im->getNumberImages();
  257. for ($i = 0; $i < $num; $i++) {
  258. $this->im->setImageIndex($i);
  259. $img = $this->get();
  260. $img->readImageBlob($this->im);
  261. if ($d != false) {
  262. $img->drawImage($d);
  263. } else {
  264. $img->cropImage($w, $h, $x, $y);
  265. }
  266. $canvas->addImage($img);
  267. $canvas->setImageDelay($img->getImageDelay());
  268. if($d == false) $canvas->setImagePage($w, $h, 0, 0);
  269. $img->destroy();
  270. unset($img);
  271. }
  272. $this->im->destroy();
  273. $this->im = $canvas;
  274. }
  275. protected function compress($canvas, $max, $num, $file)
  276. {
  277. $num = $num - 10;
  278. $temp = $file . '_temp_'.$num.'.jpg';
  279. $canvas->setCompressionQuality($num);
  280. $canvas->stripImage();
  281. $canvas->writeImage($temp);
  282. $size = abs(filesize($temp));
  283. if ($size > $max && $num > 0) {
  284. @unlink($temp);
  285. return $this->compress($canvas, $max, $num, $file);
  286. } else {
  287. $canvas->destroy();
  288. @copy($temp, $file);
  289. @unlink($temp);
  290. }
  291. }
  292. protected function create($w, $h, $t = 1)
  293. {
  294. $im = new \Imagick();
  295. if ($t == 1) {
  296. $transparent = new \ImagickPixel('#ffffff');
  297. } elseif ($t == 2) {
  298. $transparent = new \ImagickPixel('#transparent');
  299. }
  300. $im->newImage($w, $h, $transparent, 'jpg');
  301. return $im;
  302. }
  303. protected function get($im)
  304. {
  305. if ($im && strstr($im, 'http')) {
  306. $content = file_get_contents($im);
  307. $im = new \Imagick();
  308. $im->readImageBlob($content);
  309. } elseif ($im && is_file($im)) {
  310. $im = new \Imagick($im);
  311. } else {
  312. $im = new \Imagick();
  313. }
  314. return $im;
  315. }
  316. protected function get_radius($img = '', $radius = -1)
  317. {
  318. $image = $this->get($img);
  319. $image->setImageFormat('png');
  320. if ($radius == -1) {
  321. $x = $image->getImageWidth() / 2;
  322. $y = $image->getImageHeight() / 2;
  323. } else {
  324. $x = $image->getImageWidth() - $radius;
  325. $y = $image->getImageHeight() - $radius;
  326. }
  327. $image->roundCorners($x, $y);
  328. return $image;
  329. }
  330. protected function _destroy()
  331. {
  332. $this->im->destroy();
  333. $this->im = false;
  334. }
  335. }