PageRenderTime 28ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/app/Library/ImageMagic.php

https://bitbucket.org/kiruthiga208/expertplus_enc
PHP | 334 lines | 262 code | 63 blank | 9 comment | 60 complexity | 64e72ca561829730c30689637836c435 MD5 | raw file
Possible License(s): Apache-2.0, LGPL-2.1, MPL-2.0-no-copyleft-exception, BSD-3-Clause, MIT
  1. <?php
  2. /**
  3. * Image Magic class
  4. * @author: Abhimanyu Sharma <abhimanyusharma003@gmail.com>
  5. *
  6. */
  7. namespace abhimanyusharma003\Image;
  8. class Image
  9. {
  10. protected $cacheDir = 'cache/images';
  11. protected $actualCacheDir = null;
  12. protected $image = NULL;
  13. protected $format = NULL;
  14. protected $originalFile = NULL;
  15. protected $data = NULL;
  16. protected $width = NULL;
  17. protected $height = NULL;
  18. protected $operations = array();
  19. protected $prettyName = '';
  20. protected $hash = NULL;
  21. protected $file = NULL;
  22. public function __construct($path = NULL, $width = NULL, $height = NULL)
  23. {
  24. $this->file = $path;
  25. $this->width = $width;
  26. $this->height = $height;
  27. if (!(extension_loaded('imagick'))) {
  28. throw new \RuntimeException('You need to install Imagick PHP Extension OR use http://github.com/Gregwar/Image library');
  29. }
  30. $this->image = new \Imagick(public_path().'/'. $path);
  31. $this->format = $this->image->getImageFormat();
  32. }
  33. public static function open($path)
  34. {
  35. return new Image($path);
  36. }
  37. public function jpeg($quality = 80)
  38. {
  39. return $this->cacheFile('jpg', $quality);
  40. }
  41. public function png()
  42. {
  43. return $this->cacheFile('png');
  44. }
  45. public function gif()
  46. {
  47. return $this->cacheFile('gif');
  48. }
  49. public function guess()
  50. {
  51. return $this->cacheFile($this->format);
  52. }
  53. public function cacheFile($type = 'jpg', $quality = 80)
  54. {
  55. // Computes the hash
  56. $this->hash = $this->getHash($type, $quality);
  57. // Generates the cache file
  58. list($actualFile, $file) = $this->generateFileFromHash($this->hash . '.' . $type);
  59. // If the files does not exists, save it
  60. if (!file_exists($actualFile)) {
  61. $this->save($actualFile, $type, $quality);
  62. }
  63. return $this->getFilename($file);
  64. }
  65. public function getHash($type = 'guess', $quality = 80)
  66. {
  67. if (null === $this->hash) {
  68. $this->generateHash();
  69. }
  70. return $this->hash;
  71. }
  72. public function generateHash($type = 'guess', $quality = 80)
  73. {
  74. $inputInfos = 0;
  75. if ($this->file) {
  76. try {
  77. $inputInfos = filectime($this->file);
  78. } catch (\Exception $e) {
  79. }
  80. } else {
  81. $inputInfos = array($this->width, $this->height);
  82. }
  83. $datas = array(
  84. $this->file,
  85. $inputInfos,
  86. $type,
  87. $this->serializeOperations(),
  88. $quality
  89. );
  90. $this->hash = sha1(serialize($datas));
  91. }
  92. public function serializeOperations()
  93. {
  94. $datas = array();
  95. foreach ($this->operations as $operation) {
  96. $method = $operation[0];
  97. $args = $operation[1];
  98. foreach ($args as &$arg) {
  99. if ($arg instanceof Image) {
  100. $arg = $arg->getHash();
  101. }
  102. }
  103. $datas[] = array($method, $args);
  104. }
  105. return serialize($datas);
  106. }
  107. public function generateFileFromHash($hash)
  108. {
  109. $directory = $this->cacheDir;
  110. if ($this->actualCacheDir === null) {
  111. $actualDirectory = $directory;
  112. } else {
  113. $actualDirectory = $this->actualCacheDir;
  114. }
  115. for ($i = 0; $i < 5; $i++) {
  116. $c = $hash[$i];
  117. $directory .= '/' . $c;
  118. $actualDirectory .= '/' . $c;
  119. }
  120. $endName = substr($hash, 5);
  121. if ($this->prettyName) {
  122. $endName = $this->prettyName . '-' . $endName;
  123. }
  124. $file = $directory . '/' . $endName;
  125. $actualFile = $actualDirectory . '/' . $endName;
  126. return array($actualFile, $file);
  127. }
  128. public function applyOperations()
  129. {
  130. // Renders the effects
  131. foreach ($this->operations as $operation) {
  132. call_user_func_array(array($this, $operation[0]), $operation[1]);
  133. }
  134. }
  135. protected function getFilename($filename)
  136. {
  137. return $filename;
  138. }
  139. public function __call($func, $args)
  140. {
  141. $reflection = new \ReflectionClass(get_class($this));
  142. $methodName = '_' . $func;
  143. if ($reflection->hasMethod($methodName)) {
  144. $method = $reflection->getMethod($methodName);
  145. if ($method->getNumberOfRequiredParameters() > count($args)) {
  146. throw new \InvalidArgumentException('Not enough arguments given for ' . $func);
  147. }
  148. $this->addOperation($methodName, $args);
  149. return $this;
  150. }
  151. throw new \BadFunctionCallException('Invalid method: ' . $func);
  152. }
  153. protected function addOperation($method, $args)
  154. {
  155. $this->operations[] = array($method, $args);
  156. }
  157. public function save($file, $type = 'jpg', $quality = 80)
  158. {
  159. if ($file) {
  160. $directory = dirname($file);
  161. if (!is_dir($directory)) {
  162. @mkdir($directory, 0777, true);
  163. }
  164. }
  165. $this->applyOperations();
  166. $this->image->setImageCompressionQuality($quality);
  167. if ($type == 'JPG' || $type == 'jpg') {
  168. $this->image->setImageBackgroundColor('white');
  169. $this->image->flattenImages();
  170. $this->image = $this->image->flattenImages();
  171. $this->image->setImageCompression(\Imagick::COMPRESSION_JPEG);
  172. }
  173. if ($type == 'GIF' || $type == 'gif') {
  174. $this->image->setImageFormat($type);
  175. $file = preg_replace('/[^\.]*$/', '', $file);
  176. return $this->image->writeImages(public_path().'/'. $file . 'gif', true) === true;
  177. }
  178. $this->image->setImageFormat($type);
  179. $file = preg_replace('/[^\.]*$/', '', $file);
  180. $this->image->writeImage(public_path().'/'. $file . strtolower($type));
  181. return $file;
  182. }
  183. protected function _enlargeSafeResize($width, $height)
  184. {
  185. $imageWidth = $this->image->getImageWidth();
  186. $imageHeight = $this->image->getImageHeight();
  187. if ($imageWidth >= $imageHeight) {
  188. if ($imageWidth <= $width && $imageHeight <= $height)
  189. return $this->_thumbnailImage($imageWidth, $imageHeight);
  190. $wRatio = $width / $imageWidth;
  191. $hRatio = $height / $imageHeight;
  192. } else {
  193. if ($imageHeight <= $width && $imageWidth <= $height)
  194. return $this->_thumbnailImage($imageWidth, $imageHeight); // no resizing required
  195. $wRatio = $height / $imageWidth;
  196. $hRatio = $width / $imageHeight;
  197. }
  198. $resizeRatio = Min($wRatio, $hRatio);
  199. $newHeight = $imageHeight * $resizeRatio;
  200. $newWidth = $imageWidth * $resizeRatio;
  201. return $this->_thumbnailImage($newWidth, $newHeight);
  202. }
  203. protected function _thumbnailImage($width, $height)
  204. {
  205. if ($this->format == 'GIF' || $this->format == 'gif') {
  206. foreach ($this->image as $frame) {
  207. $this->image->thumbnailImage($width, $height);
  208. $frame->setImagePage($width, $height, 0, 0);
  209. }
  210. } else {
  211. $this->image->thumbnailImage($width, $height);
  212. }
  213. return $this;
  214. }
  215. protected function _cropImage($width, $height, $x = null, $y = null)
  216. {
  217. if ($this->format == 'GIF' || $this->format == 'gif') {
  218. foreach ($this->image as $frame) {
  219. $this->image->cropImage($width, $height, $x, $y);
  220. $frame->setImagePage($width, $height, 0, 0);
  221. }
  222. } else {
  223. $this->image->cropImage($width, $height, $x, $y);
  224. }
  225. return $this;
  226. }
  227. protected function _cropThumbnailImage($width, $height)
  228. {
  229. $geo = $this->image->getImageGeometry();
  230. if (($geo['width'] / $width) < ($geo['height'] / $height)) {
  231. if ($this->format == 'GIF' || $this->format == 'gif') {
  232. foreach ($this->image as $frame) {
  233. $this->image->cropImage($geo['width'], floor($height * $geo['width'] / $width), 0, (($geo['height'] - ($height * $geo['width'] / $width)) / 2));
  234. $frame->setImagePage($width, $height, 0, 0);
  235. }
  236. } else {
  237. $this->image->cropImage($geo['width'], floor($height * $geo['width'] / $width), 0, (($geo['height'] - ($height * $geo['width'] / $width)) / 2));
  238. }
  239. } else {
  240. if ($this->format == 'GIF' || $this->format == 'gif') {
  241. foreach ($this->image as $frame) {
  242. $this->image->cropImage(ceil($width * $geo['height'] / $height), $geo['height'], (($geo['width'] - ($width * $geo['height'] / $height)) / 2), 0);
  243. $frame->setImagePage($width, $height, 0, 0);
  244. }
  245. } else {
  246. $this->image->cropImage(ceil($width * $geo['height'] / $height), $geo['height'], (($geo['width'] - ($width * $geo['height'] / $height)) / 2), 0);
  247. }
  248. }
  249. if ($this->format == 'GIF' || $this->format == 'gif') {
  250. foreach ($this->image as $frame) {
  251. $this->image->ThumbnailImage($width, $height, true);
  252. $frame->setImagePage($width, $height, 0, 0);
  253. }
  254. } else {
  255. $this->image->ThumbnailImage($width, $height, true);
  256. }
  257. return $this;
  258. }
  259. protected function _resizeImage($width, $height, $filter = \imagick::DISPOSE_NONE, $blur = NULL)
  260. {
  261. if ($this->format == 'GIF' || $this->format == 'gif') {
  262. foreach ($this->image as $frame) {
  263. $this->image->resizeImage($width, $height, $filter, $blur);
  264. $frame->setImagePage($width, $height, 0, 0);
  265. }
  266. } else {
  267. $this->image->resizeImage($width, $height, $filter, $blur);
  268. }
  269. return $this;
  270. }
  271. }