PageRenderTime 58ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/protected/libs/CdImage.php

https://github.com/smarteng/onenoteme
PHP | 692 lines | 441 code | 73 blank | 178 comment | 31 complexity | 5ad770821f4ca0d38a59fc5da6148700 MD5 | raw file
  1. <?php
  2. class CdImage
  3. {
  4. const MERGE_TOP_RIGHT = 1;
  5. const MERGE_TOP_LEFT = 2;
  6. const MERGE_BOTTOM_LEFT = 3;
  7. const MERGE_BOTTOM_RIGHT = 4;
  8. const MERGE_CENTER = 5;
  9. private $_version = '1.0';
  10. private $_author = 'Chris Chen(cdcchen@gmail.com)';
  11. private $_site = 'http://www.24beta.com/';
  12. private $_image;
  13. private $_original;
  14. private $_imageType = IMAGETYPE_GIF;
  15. private $_lastSaveFile;
  16. private static $_createFunctions = array(
  17. IMAGETYPE_GIF => 'imagecreatefromgif',
  18. IMAGETYPE_JPEG => 'imagecreatefromjpeg',
  19. IMAGETYPE_PNG => 'imagecreatefrompng',
  20. IMAGETYPE_WBMP => 'imagecreatefromwbmp',
  21. IMAGETYPE_XBM => 'imagecreatefromxmb',
  22. );
  23. private static $_outputFuntions = array(
  24. IMAGETYPE_GIF => 'imagegif',
  25. IMAGETYPE_JPEG => 'imagejpeg',
  26. IMAGETYPE_PNG => 'imagepng',
  27. IMAGETYPE_WBMP => 'imagewbmp',
  28. IMAGETYPE_XBM => 'imagexmb',
  29. );
  30. public $fontpath;
  31. /**
  32. * 构造函数
  33. * @param string $data 图像路径或图像数据
  34. */
  35. public function __construct($data = null)
  36. {
  37. $path = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'fonts' . DIRECTORY_SEPARATOR;
  38. $this->setFontPath($path);
  39. if (null !== $data)
  40. $this->load($data);
  41. }
  42. public function setFontPath($path)
  43. {
  44. if (file_exists($path)) {
  45. $this->fontpath = $path;
  46. return true;
  47. }
  48. else
  49. return false;
  50. }
  51. /**
  52. * 从文件地址载入图像
  53. * @param string $data 图像路径或图像数据
  54. * @return CdImage CdImage对象本身
  55. */
  56. public function load($data)
  57. {
  58. $image = self::loadImage($data);
  59. $this->_image = $this->_original = $image;
  60. if (file_exists($data)) {
  61. $info = getimagesize($data);
  62. $this->_imageType = $info[2];
  63. }
  64. return $this;
  65. }
  66. /**
  67. * 从文件地址载入图像
  68. * @param string $file 图像路径
  69. * @return resource 图像资源
  70. */
  71. public static function loadFromFile($file)
  72. {
  73. $info = getimagesize($file);
  74. $type = $info[2];
  75. if (!array_key_exists($type, self::$_createFunctions))
  76. throw new Exception('不支持' . $type . '图像格式', 0);
  77. $func = self::$_createFunctions[$type];
  78. $image = $func($file);
  79. return $image;
  80. }
  81. /**
  82. * 从图像数据流载入图像
  83. * @param string $filename 图像数据
  84. * @return resource 图像资源
  85. */
  86. public static function loadFromStream($data)
  87. {
  88. return imagecreatefromstring($data);
  89. }
  90. /**
  91. * @param string $data 图像路径或图像数据
  92. * @return resource 图像资源
  93. */
  94. public static function loadImage($data)
  95. {
  96. if (file_exists($data)) {
  97. $image = self::loadFromFile($data);
  98. }
  99. else
  100. $image = self::loadFromStream($data);
  101. return $image;
  102. }
  103. /**
  104. * 返回图像宽度
  105. * @return integer 图像的宽度
  106. */
  107. public function width()
  108. {
  109. return imagesx($this->_image);
  110. }
  111. /**
  112. * 返回图像高度
  113. * @return integer 图像高度
  114. */
  115. public function height()
  116. {
  117. return imagesy($this->_image);
  118. }
  119. /**
  120. * 将图片数据还原为初始值
  121. * @return CdImage CdImage对象本身
  122. */
  123. public function revert()
  124. {
  125. $this->_image = $this->_original;
  126. return $this;
  127. }
  128. public function getType()
  129. {
  130. return $this->_imageType;
  131. }
  132. public function getMimeType()
  133. {
  134. return image_type_to_mime_type($this->_imageType);
  135. }
  136. public function getExtName()
  137. {
  138. return image_type_to_extension($this->_imageType);
  139. }
  140. public function convertType($type)
  141. {
  142. if (!array_key_exists($key, self::$_createFunctions))
  143. throw new Exception('不支持此类型', 0);
  144. $this->_imageType = $type;
  145. }
  146. /**
  147. * 保存图像到一个文件中
  148. * @param string $filename 图片文件路径,不带扩展名
  149. * @param integer $mode 图像文件的权限
  150. * @return CdImage CdImage对象本身
  151. */
  152. public function save($filename, $mode = null)
  153. {
  154. $filename .= $this->getExtName();
  155. $func = self::$_outputFuntions[$this->_imageType];
  156. self::saveAlpha($this->_image);
  157. if (!$func($this->_image, $filename))
  158. return false;
  159. $this->_lastSaveFile = $filename;
  160. if ($mode !== null) {
  161. chmod($filename, $mode);
  162. }
  163. return $this;
  164. }
  165. /**
  166. * 将图像保存为gif类型
  167. * @param string $filename 图片文件路径,不带扩展名
  168. * @param integer $mode 图像文件的权限
  169. * @return CdImage CdImage对象本身
  170. */
  171. public function saveAsGif($filename, $mode = null)
  172. {
  173. $filename .= image_type_to_extension(IMAGETYPE_GIF);
  174. if (!imagegif($this->_image, $filename))
  175. return false;
  176. $this->_lastSaveFile = $filename;
  177. if ($mode !== null) {
  178. chmod($filename, $mode);
  179. }
  180. return $this;
  181. }
  182. /**
  183. * 将图像保存为jpeg类型
  184. * @param string $filename 图片文件路径,不带扩展名
  185. * @param integer $quality 图像质量,取值为0-100
  186. * @param integer $mode 图像文件的权限
  187. * @return CdImage CdImage对象本身
  188. */
  189. public function saveAsJpeg($filename, $quality = 75, $mode = null)
  190. {
  191. $filename .= image_type_to_extension(IMAGETYPE_JPEG);
  192. if (!imagejpeg($this->_image, $filename, $quality))
  193. return false;
  194. $this->_lastSaveFile = $filename;
  195. if ($mode !== null) {
  196. chmod($filename, $mode);
  197. }
  198. return $this;
  199. }
  200. /**
  201. * 将图像保存为png类型
  202. * @param string $filename 图片文件路径,不带扩展名
  203. * @param integer $quality 图像质量,取值为0-9
  204. * @param integer $filters PNG图像过滤器,取值参考imagepng函数
  205. * @param integer $mode 图像文件的权限
  206. * @return CdImage CdImage对象本身
  207. */
  208. public function saveAsPng($filename, $quality = 9, $filters = 0, $mode = null)
  209. {
  210. $filename .= image_type_to_extension(IMAGETYPE_PNG);
  211. self::saveAlpha($this->_image);
  212. if (!imagepng($this->_image, $filename, $quality, $filters))
  213. return false;
  214. $this->_lastSaveFile = $filename;
  215. if ($mode !== null) {
  216. chmod($filename, $mode);
  217. }
  218. return $this;
  219. }
  220. /**
  221. * 将图像保存为wbmp类型
  222. * @param string $filename 图片文件路径,不带扩展名
  223. * @param integer $foreground 前景色,取值为imagecolorallocate()的返回的颜色标识符
  224. * @param integer $mode 图像文件的权限
  225. * @return CdImage CdImage对象本身
  226. */
  227. public function saveAsWbmp($filename, $foreground = 0, $mode = null)
  228. {
  229. $filename .= image_type_to_extension(IMAGETYPE_WBMP);
  230. if (!imagewbmp($this->_image, $filename, $foreground))
  231. return false;
  232. $this->_lastSaveFile = $filename;
  233. if ($mode !== null) {
  234. chmod($filename, $mode);
  235. }
  236. return $this;
  237. }
  238. /**
  239. * 将图像保存为xbm类型
  240. * @param string $filename 图片文件路径,不带扩展名
  241. * @param integer $foreground 前景色,取值为imagecolorallocate()的返回的颜色标识符
  242. * @param integer $mode 图像文件的权限
  243. * @return CdImage CdImage对象本身
  244. */
  245. public function saveAsXbm($filename, $foreground = 0, $mode = null)
  246. {
  247. $filename .= image_type_to_extension(IMAGETYPE_XBM);
  248. if (!imagexbm($this->_image, $filename, $foreground))
  249. return false;
  250. $this->_lastSaveFile = $filename;
  251. if ($mode !== null) {
  252. chmod($filename, $mode);
  253. }
  254. return $this;
  255. }
  256. public function filename()
  257. {
  258. return $this->_lastSaveFile ? basename($this->_lastSaveFile) : '';
  259. }
  260. /**
  261. * 按照图像原来的类型输出图像数据
  262. */
  263. public function output()
  264. {
  265. $contentType = image_type_to_mime_type($this->_imageType);
  266. header('Content-Type: ' . $contentType);
  267. $func = self::$_outputFuntions[$this->_imageType];
  268. $func($this->_image);
  269. }
  270. /**
  271. * 以gif类型输出图像数据
  272. */
  273. public function outputGif()
  274. {
  275. header('Content-Type: ' . image_type_to_mime_type(IMAGETYPE_GIF));
  276. imagegif($this->_image);
  277. }
  278. /**
  279. * 以jpge类型输出图像数据
  280. */
  281. public function outputJpeg($quality = 75)
  282. {
  283. header('Content-Type: ' . image_type_to_mime_type(IMAGETYPE_JPEG));
  284. imagejpeg($this->_image, $quality);
  285. }
  286. /**
  287. * 以png类型输出图像数据
  288. * @param integer $quality 图像质量,取值为0-9
  289. * @param integer $filters PNG图像过滤器,取值参考imagepng函数
  290. */
  291. public function outputPng($quality = 9, $filters = 0)
  292. {
  293. header('Content-Type: ' . image_type_to_mime_type(IMAGETYPE_PNG));
  294. imagepng($this->_image, $quality, $filters);
  295. }
  296. /**
  297. * 以wbmp类型输出图像数据
  298. */
  299. public function outputWbmp($foreground = 0)
  300. {
  301. header('Content-Type: ' . image_type_to_mime_type(IMAGETYPE_WBMP));
  302. imagewbmp($this->_image, $foreground);
  303. }
  304. /**
  305. * 以xbm类型输出图像数据
  306. */
  307. public function outputXbm($foreground = 0)
  308. {
  309. header('Content-Type: ' . image_type_to_mime_type(IMAGETYPE_XBM));
  310. imagewxbm($this->_image, $foreground);
  311. }
  312. public function outputRaw()
  313. {
  314. ob_start();
  315. $func = self::$_outputFuntions[$this->_imageType];
  316. $func($this->_image);
  317. $content = ob_get_contents();
  318. ob_end_clean();
  319. return $content;
  320. }
  321. public function outputRawGif()
  322. {
  323. ob_start();
  324. imagegif($this->_image);
  325. $content = ob_get_contents();
  326. ob_end_clean();
  327. return $content;
  328. }
  329. public function outputRawJpeg($quality = 100)
  330. {
  331. ob_start();
  332. imagejpeg($this->_image, null, $quality);
  333. $content = ob_get_contents();
  334. ob_end_clean();
  335. return $content;
  336. }
  337. public function outputRawPng($quality = 9, $filters = 0)
  338. {
  339. ob_start();
  340. imagepng($this->_image, null, $quality, $filters);
  341. $content = ob_get_contents();
  342. ob_end_clean();
  343. return $content;
  344. }
  345. public function outputRawWbmp($foreground = 0)
  346. {
  347. ob_start();
  348. imagewbmp($this->_image, null, $foreground);
  349. $content = ob_get_contents();
  350. ob_end_clean();
  351. return $content;
  352. }
  353. public function outputRawXbm($foreground = 0)
  354. {
  355. ob_start();
  356. imagewxbm($this->_image, null, $foreground);
  357. $content = ob_get_contents();
  358. ob_end_clean();
  359. return $content;
  360. }
  361. /**
  362. * 等比例绽放图像
  363. * @param integer $scale 绽放值,取值为0-100
  364. * @return CdImage CdImage对象本身
  365. */
  366. public function scale($scale)
  367. {
  368. $width = $this->width() * $scale/100;
  369. $height = $this->height() * $scale/100;
  370. $this->resize($width, $height);
  371. return $this;
  372. }
  373. /**
  374. * 根据设定高度等比例绽放图像
  375. * @param integer $height 图像高度
  376. * @return CdImage CdImage对象本身
  377. */
  378. public function resizeToHeight($height)
  379. {
  380. if ($height >= $this->height())
  381. return $this;
  382. $ratio = $height / $this->height();
  383. $width = $this->width() * $ratio;
  384. $this->resize($width, $height);
  385. return $this;
  386. }
  387. /**
  388. * 根据设定宽度等比例绽放图像
  389. * @param integer $width 图像宽度
  390. * @return CdImage CdImage对象本身
  391. */
  392. public function resizeToWidth($width)
  393. {
  394. if ($width >= $this->width())
  395. return $this;
  396. $ratio = $width / $this->width();
  397. $height = $this->height() * $ratio;
  398. $this->resize($width, $height);
  399. return $this;
  400. }
  401. /**
  402. * 改变图像大小
  403. * @param integer $width 图像宽度
  404. * @param integer $height 图像高度
  405. * @return CdImage CdImage对象本身
  406. */
  407. public function resize($width, $height)
  408. {
  409. $image = imagecreatetruecolor($width, $height);
  410. self::saveAlpha($this->_image);
  411. self::saveAlpha($image);
  412. imagecopyresampled($image, $this->_image, 0, 0, 0, 0, $width, $height, $this->width(), $this->height());
  413. $this->_image = $image;
  414. return $this;
  415. }
  416. /**
  417. * 裁剪图像
  418. * @param integer $width 图像宽度
  419. * @param integer $height 图像高度
  420. * @return CdImage CdImage对象本身
  421. */
  422. public function crop($width, $height)
  423. {
  424. $image = imagecreatetruecolor($width, $height);
  425. $wm = $this->width() / $width;
  426. $hm = $this->height() / $height;
  427. $h_height = $height / 2;
  428. $w_height = $width / 2;
  429. if ($this->width() > $this->height()) {
  430. $adjusted_width = $this->width() / $hm;
  431. $half_width = $adjusted_width / 2;
  432. $int_width = $half_width - $w_height;
  433. imagecopyresampled($image, $this->_image, -$int_width, 0, 0, 0, $adjusted_width, $height, $this->width(), $this->height());
  434. }
  435. elseif (($this->width() < $this->height()) || ($this->width() == $this->height())) {
  436. $adjusted_height = $this->height() / $wm;
  437. $half_height = $adjusted_height / 2;
  438. $int_height = $half_height - $h_height;
  439. imagecopyresampled($image, $this->_image, 0, -$int_height, 0, 0, $width, $adjusted_height, $this->width(), $this->height());
  440. }
  441. else {
  442. imagecopyresampled($image, $this->_image, 0, 0, 0, 0, $width, $height, $this->width(), $this->height());
  443. }
  444. $this->_image = $image;
  445. return $this;
  446. }
  447. /**
  448. * 顺时针旋转图片
  449. * @param integer $degree 取值为0-360
  450. * @return CdImage CdImage对象本身
  451. */
  452. public function rotate($degree = 90)
  453. {
  454. $degree = (int)$degree;
  455. $this->_image = imagerotate($this->_image, $degree, 0);
  456. return $this;
  457. }
  458. /**
  459. * 将图像转换为灰度的
  460. * @return CdImage CdImage对象本身
  461. */
  462. public function gray()
  463. {
  464. imagefilter($this->_image, IMG_FILTER_GRAYSCALE);
  465. return $this;
  466. }
  467. /**
  468. * 将图像颜色反转
  469. * @return CdImage CdImage对象本身
  470. */
  471. public function negate()
  472. {
  473. imagefilter($this->_image, IMG_FILTER_NEGATE);
  474. return $this;
  475. }
  476. /**
  477. * 调整图像亮度
  478. * @param integer $bright 亮度值
  479. * @return CdImage CdImage对象本身
  480. */
  481. public function brightness($bright)
  482. {
  483. $bright = (int)$bright;
  484. ($bright > 0) && imagefilter($this->_image, IMG_FILTER_BRIGHTNESS, $bright);
  485. return $this;
  486. }
  487. /**
  488. * 调整图像对比度
  489. * @param integer $contrast 对比度值
  490. * @return CdImage CdImage对象本身
  491. */
  492. public function contrast($contrast)
  493. {
  494. $contrast = (int)$contrast;
  495. ($contrast > 0) && imagefilter($this->_image, IMG_FILTER_CONTRAST, $contrast);
  496. return $this;
  497. }
  498. /**
  499. * 将图像浮雕化
  500. * @return CdImage CdImage对象本身
  501. */
  502. public function emboss()
  503. {
  504. imagefilter($this->_image, IMG_FILTER_EMBOSS,0);
  505. return $this;
  506. }
  507. /**
  508. * 让图像柔滑
  509. * @param integer $smooth 柔滑度值
  510. * @return CdImage CdImage对象本身
  511. */
  512. public function smooth($smooth)
  513. {
  514. $smooth = (int)$smooth;
  515. ($smooth > 0) && imagefilter($this->_image, IMG_FILTER_SMOOTH, $smooth);
  516. return $this;
  517. }
  518. /**
  519. * 将图像使用高斯模糊
  520. * @return CdImage CdImage对象本身
  521. */
  522. public function blur()
  523. {
  524. imagefilter($this->_image, IMG_FILTER_GAUSSIAN_BLUR);
  525. return $this;
  526. }
  527. /**
  528. * 在图像上添加文字
  529. * @param string $text 添加的文字
  530. * @param integer $opacity 不透明度,值为0-1
  531. * @param 文字添加位置 $position
  532. * @param string $font 字体文件路径
  533. * @param integer $size 文字大小
  534. * @param integer $color 颜色值
  535. * @return CdImage CdImage对象本身
  536. */
  537. public function text($text, $opacity = 0.5, $position = 0, $font, $size, $color)
  538. {
  539. imagettftext($this->_image, $size, 0, $x, $y, $color, $font, $text);
  540. return $this;
  541. }
  542. /**
  543. * 将一个图像合并到画布上
  544. * @param string $data 图像的二进制数据
  545. * @param constant $position 合并位置
  546. * @param integer $opacity 不透明度,取值为0-100
  547. */
  548. public function merge($data, $opacity = 100, $position = self::MERGE_BOTTOM_RIGHT)
  549. {
  550. $src = self::loadImage($data);
  551. if (!is_resource($src))
  552. throw new Exception('图像数据错误', 0);
  553. $w = imagesx($src);
  554. $h = imagesy($src);
  555. $image = imagecreatetruecolor($w, $h);
  556. imagealphablending($this->_image, true);
  557. imagealphablending($image, true);
  558. $pos = self::getPosition($position, $this->_image, $src);
  559. imagecopyresampled($image, $this->_image, 0, 0, $pos[0], $pos[1], $w, $h, $w, $h);
  560. self::saveAlpha($src);
  561. imagecopy($image, $src, 0, 0, 0, 0, $w, $h);
  562. imagecopymerge($this->_image, $image, $pos[0], $pos[1], 0, 0, $w, $h, $opacity);
  563. return $this;
  564. }
  565. public static function getPosition($position, $dst, $src)
  566. {
  567. $dstW = imagesx($dst);
  568. $dstH = imagesy($dst);
  569. $srcW = imagesx($src);
  570. $srcH = imagesy($src);
  571. switch ($position) {
  572. case self::MERGE_TOP_LEFT:
  573. return array(0, 0);
  574. break;
  575. case self::MERGE_TOP_RIGHT:
  576. return array($dstW-$srcW, 0);
  577. break;
  578. case self::MERGE_BOTTOM_RIGHT:
  579. return array($dstW-$srcW, $dstH-$srcH);
  580. break;
  581. case self::MERGE_BOTTOM_LEFT:
  582. return array(0, $dstH-$srcH);
  583. break;
  584. case self::MERGE_CENTER:
  585. $x = ($dstW - $srcW) / 2;
  586. $y = ($dstH - $srcH) / 2;
  587. return array((int)$x, (int)$y);
  588. break;
  589. default:
  590. return false;
  591. break;
  592. }
  593. }
  594. public static function saveAlpha(&$im)
  595. {
  596. imagealphablending($im, false);
  597. imagesavealpha($im, true);
  598. }
  599. public function getSite()
  600. {
  601. return $this->_site;
  602. }
  603. public function getVersion()
  604. {
  605. return $this->_version;
  606. }
  607. public function getAuthor()
  608. {
  609. return $this->_author;
  610. }
  611. /**
  612. * 析构函数
  613. */
  614. public function __destruct()
  615. {
  616. is_resource($this->_image) && imagedestroy($this->_image);
  617. is_resource($this->_original) && imagedestroy($this->_original);
  618. }
  619. }