/mzz/system/service/image.php

https://github.com/greevex/mzz-framework-blank-application · PHP · 236 lines · 172 code · 42 blank · 22 comment · 39 complexity · aaadb9093c21938e273214d17472d2fb MD5 · raw file

  1. <?php
  2. /**
  3. * $URL: svn://svn.mzz.ru/mzz/trunk/system/service/image.php $
  4. *
  5. * MZZ Content Management System (c) 2008
  6. * Website : http://www.mzz.ru
  7. *
  8. * This program is free software and released under
  9. * the GNU Lesser General Public License (See /docs/LGPL.txt).
  10. *
  11. * @link http://www.mzz.ru
  12. * @version $Id: image.php 4390 2011-02-17 06:27:41Z jonix $
  13. */
  14. /**
  15. * image: класс для работы с изображениями
  16. *
  17. * @package system
  18. * @subpackage service
  19. * @version 0.1
  20. */
  21. class image
  22. {
  23. protected $image;
  24. protected $path = null;
  25. protected $type;
  26. protected $ext;
  27. protected $width;
  28. protected $height;
  29. public function __construct($image_src, $type = null)
  30. {
  31. if (is_resource($image_src)) {
  32. $width = imagesx($image_src);
  33. $height = imagesy($image_src);
  34. if ($width === false || $height === false) {
  35. throw new mzzRuntimeException('Не удалось получить данные о размере изображения');
  36. }
  37. $this->image = $image_src;
  38. $this->type = $type;
  39. $this->ext = $this->getExtByType($type);
  40. $this->width = $width;
  41. $this->height = $height;
  42. } else {
  43. if (!is_file($image_src) && is_writable($image_src)) {
  44. throw new mzzIoException($image_src);
  45. }
  46. $this->path = $image_src;
  47. list($this->width, $this->height, $this->type) = getimagesize($image_src);
  48. $this->ext = $this->getExtByType($this->type);
  49. if (!($this->image = call_user_func('imagecreatefrom' . $this->ext, $image_src))) {
  50. throw new mzzRuntimeException('imagecreatefrom' . $this->ext . ' failed');
  51. }
  52. }
  53. }
  54. public function width()
  55. {
  56. return $this->width;
  57. }
  58. public function height()
  59. {
  60. return $this->height;
  61. }
  62. public function resize($width, $height)
  63. {
  64. if (!in_array($this->type, array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) {
  65. throw new mzzRuntimeException('Неверный тип файла для изменения размера');
  66. }
  67. $width_orig = $this->width;
  68. $height_orig = $this->height;
  69. $aspect_w = $width_orig / $width;
  70. $aspect_h = $height_orig / $height;
  71. $aspect = max($aspect_h, $aspect_w);
  72. if ($aspect <= 1) {
  73. $width = $width_orig;
  74. $height = $height_orig;
  75. } else {
  76. $width = round($width_orig / $aspect);
  77. $height = round($height_orig / $aspect);
  78. }
  79. if (!($image_resized = imagecreatetruecolor($width, $height))) {
  80. throw new mzzRuntimeException('imagecreatetruecolor failed');
  81. }
  82. if ($this->ext == 'png') {
  83. if (!imagealphablending($image_resized, false)) {
  84. throw new mzzRuntimeException('imagealphablending failed');
  85. }
  86. if (!imagesavealpha($image_resized, true)) {
  87. throw new mzzRuntimeException('imagesavealpha failed');
  88. }
  89. } elseif ($this->ext == 'gif') {
  90. if ($trans_color = imagecolorallocate($this->image, 255, 255, 255)) {
  91. imagecolortransparent($this->image, $trans_color);
  92. }
  93. }
  94. if (!imagecopyresampled($image_resized, $this->image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig)) {
  95. throw new mzzRuntimeException('imagecopyresampled failed');
  96. }
  97. $this->width = $width;
  98. $this->height = $height;
  99. $this->image = $image_resized;
  100. return new image($this->image, $this->type, $this->width, $this->height);
  101. }
  102. public function resizeWithCrop($width, $height)
  103. {
  104. if (!in_array($this->type, array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) {
  105. throw new mzzRuntimeException('Неверный тип файла для изменения размера');
  106. }
  107. $width_orig = $this->width;
  108. $height_orig = $this->height;
  109. $aspect_w = $width_orig / $width;
  110. $aspect_h = $height_orig / $height;
  111. $aspect = min($aspect_h, $aspect_w);
  112. if ($aspect <= 1) {
  113. $thmb_width = $width_orig;
  114. $thmb_height = $height_orig;
  115. } else {
  116. $thmb_width = round($width_orig / $aspect);
  117. $thmb_height = round($height_orig / $aspect);
  118. }
  119. if (!($image_resized = imagecreatetruecolor($width, $height))) {
  120. throw new mzzRuntimeException('imagecreatetruecolor failed');
  121. }
  122. if ($this->ext == 'png') {
  123. if (!imagealphablending($image_resized, false)) {
  124. throw new mzzRuntimeException('imagealphablending failed');
  125. }
  126. if (!imagesavealpha($image_resized, true)) {
  127. throw new mzzRuntimeException('imagesavealpha failed');
  128. }
  129. } elseif ($this->ext == 'gif') {
  130. if (!($trans_color = imagecolorallocate($this->image, 255, 255, 255))) {
  131. throw new mzzRuntimeException('imagecolorallocate failed');
  132. }
  133. imagecolortransparent($this->image, $trans_color);
  134. }
  135. $startX = 0;
  136. if ($thmb_width > $width) {
  137. //$startX = (($width_orig - $thmb_width / $aspect_w) / 2) - ($thmb_width / $aspect_w);
  138. $startX = ($width - $thmb_width) / 2;
  139. }
  140. $startY = 0;
  141. if ($thmb_height > $height) {
  142. //$startY = (($height_orig - $thmb_height / $aspect_h) / 2) - ($thmb_height / $aspect_h);
  143. $startY = ($height - $thmb_height) / 2;
  144. }
  145. if (!imagecopyresampled($image_resized, $this->image, $startX, $startY, 0, 0, $thmb_width, $thmb_height, $width_orig, $height_orig)) {
  146. throw new mzzRuntimeException('imagecopyresampled failed');
  147. }
  148. $this->width = $width;
  149. $this->height = $height;
  150. $this->image = $image_resized;
  151. return new image($this->image, $this->type, $this->width, $this->height);
  152. }
  153. public function save($filename = null)
  154. {
  155. if (!$filename) {
  156. if (is_null($this->path)) {
  157. throw new mzzRuntimeException('Укажите путь для сохранения');
  158. }
  159. $filename = $this->path;
  160. }
  161. $args = array($this->image, $filename);
  162. if ($this->ext == 'jpeg') {
  163. $args[] = 100;
  164. }
  165. if (call_user_func_array('image' . $this->ext, $args)) {
  166. return $filename;
  167. } else {
  168. throw new mzzRuntimeException('image' . $this->ext . ' failed');
  169. }
  170. }
  171. protected function getExtByType($type)
  172. {
  173. //@todo: подумать над поддержкой всех типов
  174. $types = array(
  175. IMAGETYPE_GIF => 'gif',
  176. IMAGETYPE_JPEG => 'jpeg',
  177. IMAGETYPE_PNG => 'png',
  178. IMAGETYPE_SWF => 'swf',
  179. IMAGETYPE_PSD => 'psd',
  180. IMAGETYPE_BMP => 'bmp',
  181. IMAGETYPE_TIFF_II => 'tiff',
  182. IMAGETYPE_TIFF_MM => 'tiff'
  183. );
  184. if (!isset($types[$type])) {
  185. throw new mzzRuntimeException('Неверный тип файла');
  186. }
  187. return $types[$type];
  188. }
  189. public function getExt()
  190. {
  191. return $this->ext == 'jpeg' ? 'jpg' : $this->ext;
  192. }
  193. }
  194. ?>