PageRenderTime 61ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/plugins/media/libs/mm/src/Media/Process/Adapter/Gd.php

https://github.com/markaspot/Mark-a-Spot-1.6-CakePHP
PHP | 311 lines | 270 code | 24 blank | 17 comment | 24 complexity | 814211ecb9049cb8cb375eec3575a3b4 MD5 | raw file
  1. <?php
  2. /**
  3. * mm: the PHP media library
  4. *
  5. * Copyright (c) 2007-2010 David Persson
  6. *
  7. * Distributed under the terms of the MIT License.
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright 2007-2010 David Persson <nperson@gmx.de>
  11. * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  12. * @link http://github.com/davidpersson/mm
  13. */
  14. require_once 'Media/Process/Adapter.php';
  15. require_once 'Mime/Type.php';
  16. /**
  17. * This media process adapter allows for interfacing with the native `gd` pecl extension.
  18. *
  19. * @link http://php.net/gd
  20. */
  21. class Media_Process_Adapter_Gd extends Media_Process_Adapter {
  22. protected $_object;
  23. protected $_formatMap = array(
  24. 'image/jpeg' => 'jpeg',
  25. 'image/gif' => 'gif',
  26. 'image/png' => 'png',
  27. 'image/gd' => 'gd',
  28. 'image/vnd.wap.wbmp' => 'wbmp',
  29. 'image/xbm' => 'xbm',
  30. );
  31. protected $_format;
  32. protected $_compression;
  33. protected $_pngFilter;
  34. public function __construct($handle) {
  35. $mimeType = Mime_Type::guessType($handle);
  36. if (!isset($this->_formatMap[$mimeType])) {
  37. throw new OutOfBoundsException("Could not map MIME-type `{$mimeType}` to format.");
  38. }
  39. $this->_format = $this->_formatMap[$mimeType];
  40. $this->_object = imageCreateFromString(stream_get_contents($handle));
  41. if (!$this->_isResource($this->_object)) {
  42. throw new Exception("Was not able to create image from handle.");
  43. }
  44. if (imageIsTrueColor($this->_object)) {
  45. imageAlphaBlending($this->_object, false);
  46. imageSaveAlpha($this->_object, true);
  47. }
  48. }
  49. public function __destruct() {
  50. if ($this->_isResource($this->_object)) {
  51. imageDestroy($this->_object);
  52. }
  53. }
  54. public function store($handle) {
  55. $args = array($this->_object);
  56. switch ($this->_format) {
  57. case 'jpeg':
  58. if (isset($this->_compression)) {
  59. if (count($args) == 1) {
  60. $args[] = null;
  61. }
  62. $args[] = $this->_compression;
  63. }
  64. break;
  65. case 'png':
  66. if (isset($this->_compression)) {
  67. if (count($args) == 1) {
  68. $args[] = null;
  69. }
  70. $args[] = $this->_compression;
  71. if (isset($this->_pngFilter)) {
  72. $args[] = $this->_pngFilter;
  73. }
  74. }
  75. break;
  76. }
  77. ob_start();
  78. call_user_func_array('image' . $this->_format, $args);
  79. $blob = ob_get_clean();
  80. rewind($handle);
  81. return fwrite($handle, $blob);
  82. }
  83. public function convert($mimeType) {
  84. if (Mime_Type::guessName($mimeType) != 'image') {
  85. return true;
  86. }
  87. if (isset($this->_formatMap[$mimeType])) {
  88. return $this->_format = $this->_formatMap[$mimeType];
  89. }
  90. return false;
  91. }
  92. public function passthru($key, $value) {
  93. throw new Exception("The adapter has no passthru support.");
  94. }
  95. public function compress($value) {
  96. switch ($this->_format) {
  97. case 'jpeg':
  98. $this->_compression = (integer) (100 - ($value * 10));
  99. break;
  100. case 'png':
  101. if (version_compare(PHP_VERSION, '5.1.2', '>=')) {
  102. $this->_compression = (integer) $value;
  103. }
  104. if (version_compare(PHP_VERSION, '5.1.3', '>=')) {
  105. $filter = ($value * 10) % 10;
  106. $map = array(
  107. 0 => PNG_FILTER_NONE,
  108. 1 => PNG_FILTER_SUB,
  109. 2 => PNG_FILTER_UP,
  110. 3 => PNG_FILTER_AVG,
  111. 4 => PNG_FILTER_PAETH,
  112. );
  113. if (array_key_exists($filter, $map)) {
  114. $this->_pngFilter = $map[$filter];
  115. } elseif ($filter == 5) {
  116. if (intval($value) <= 5 && imageIsTrueColor($this->_object)) {
  117. $this->_pngFilter = PNG_ALL_FILTERS;
  118. } else {
  119. $this->_pngFilter = PNG_NO_FILTER;
  120. }
  121. } else {
  122. $this->_pngFilter = PNG_ALL_FILTERS;
  123. }
  124. }
  125. break;
  126. }
  127. return true;
  128. }
  129. public function profile($type, $data = null) {
  130. throw new Exception("The adapter doesn't support the `profile` action.");
  131. }
  132. public function strip($type) {
  133. throw new Exception("The adapter doesn't support the `strip` action.");
  134. }
  135. public function depth($value) {
  136. throw new Exception("The adapter doesn't support the `depth` action.");
  137. }
  138. public function interlace($value) {
  139. if (in_array($this->_format, array('jpeg', 'png', 'gif'))) {
  140. imageInterlace($this->_object, $value ? 1 : 0);
  141. return true;
  142. }
  143. return false;
  144. }
  145. public function crop($left, $top, $width, $height) {
  146. $left = (integer) $left;
  147. $top = (integer) $top;
  148. $width = (integer) $width;
  149. $height = (integer) $height;
  150. $image = imageCreateTrueColor($width, $height);
  151. $this->_adjustTransparency($this->_object, $image);
  152. if ($this->_isTransparent($this->_object)) {
  153. imageCopyResized(
  154. $image,
  155. $this->_object,
  156. 0, 0,
  157. $left, $top,
  158. $width, $height,
  159. $width, $height
  160. );
  161. } else {
  162. imageCopyResampled(
  163. $image,
  164. $this->_object,
  165. 0, 0,
  166. $left, $top,
  167. $width, $height,
  168. $width, $height
  169. );
  170. }
  171. if ($this->_isResource($image)) {
  172. $this->_object = $image;
  173. return true;
  174. }
  175. return false;
  176. }
  177. public function resize($width, $height) {
  178. $width = (integer) $width;
  179. $height = (integer) $height;
  180. $image = imageCreateTrueColor($width, $height);
  181. $this->_adjustTransparency($this->_object, $image);
  182. if ($this->_isTransparent($this->_object)) {
  183. imageCopyResized(
  184. $image,
  185. $this->_object,
  186. 0, 0,
  187. 0, 0,
  188. $width, $height,
  189. $this->width(), $this->height()
  190. );
  191. } else {
  192. imageCopyResampled(
  193. $image,
  194. $this->_object,
  195. 0, 0,
  196. 0, 0,
  197. $width, $height,
  198. $this->width(), $this->height()
  199. );
  200. }
  201. if ($this->_isResource($image)) {
  202. $this->_object = $image;
  203. return true;
  204. }
  205. return false;
  206. }
  207. public function cropAndResize($cropLeft, $cropTop, $cropWidth, $cropHeight, $resizeWidth, $resizeHeight) {
  208. $cropLeft = (integer) $cropLeft;
  209. $cropTop = (integer) $cropTop;
  210. $cropWidth = (integer) $cropWidth;
  211. $cropHeight = (integer) $cropHeight;
  212. $resizeWidth = (integer) $resizeWidth;
  213. $resizeHeight = (integer) $resizeHeight;
  214. $image = imageCreateTrueColor($resizeWidth, $resizeHeight);
  215. $this->_adjustTransparency($this->_object, $image);
  216. if ($this->_isTransparent($this->_object)) {
  217. imageCopyResized(
  218. $image,
  219. $this->_object,
  220. 0, 0,
  221. $cropLeft, $cropTop,
  222. $resizeWidth, $resizeHeight,
  223. $cropWidth, $cropHeight
  224. );
  225. } else {
  226. imageCopyResampled(
  227. $image,
  228. $this->_object,
  229. 0, 0,
  230. $cropLeft, $cropTop,
  231. $resizeWidth, $resizeHeight,
  232. $cropWidth, $cropHeight
  233. );
  234. }
  235. if ($this->_isResource($image)) {
  236. $this->_object = $image;
  237. return true;
  238. }
  239. return false;
  240. }
  241. public function width() {
  242. return imageSX($this->_object);
  243. }
  244. public function height() {
  245. return imageSY($this->_object);
  246. }
  247. protected function _isResource($image) {
  248. return is_resource($image) && get_resource_type($image) == 'gd';
  249. }
  250. protected function _isTransparent($image) {
  251. return imageColorTransparent($image) >= 0;
  252. }
  253. protected function _adjustTransparency(&$source, &$target) {
  254. if ($this->_isTransparent($source)) {
  255. $rgba = imageColorsForIndex($source, imageColorTransparent($source));
  256. $color = imageColorAllocate($target, $rgba['red'], $rgba['green'], $rgba['blue']);
  257. imageColorTransparent($target, $color);
  258. imageFill($target, 0, 0, $color);
  259. } else {
  260. if ($this->_format == 'png') {
  261. imageAlphaBlending($target, false);
  262. imageSaveAlpha($target, true);
  263. } elseif ($this->_format != 'gif') {
  264. $white = imageColorAllocate($target, 255, 255, 255);
  265. imageFill($target, 0, 0 , $white);
  266. }
  267. }
  268. }
  269. }
  270. ?>