PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/system/classes/helpers/image.php

http://github.com/enormego/EightPHP
PHP | 463 lines | 359 code | 71 blank | 33 comment | 63 complexity | a6360e685a25954b89f7b2e587409225 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * Image helper class.
  4. *
  5. * @package System
  6. * @subpackage Helpers
  7. * @author EightPHP Development Team
  8. * @copyright (c) 2009-2010 EightPHP
  9. * @license http://license.eightphp.com
  10. */
  11. class image_Core {
  12. const GIF = 0x00000001;
  13. const PNG = 0x00000010;
  14. const JPG = 0x00000100;
  15. const JPEG = 0x00000100;
  16. public static function is_animated($input) {
  17. if(!file_exists($input)) {
  18. $filecontents = $input;
  19. } else {
  20. $filecontents = file_get_contents($input);
  21. }
  22. $str_loc=0;
  23. $count=0;
  24. while ($count < 2) {
  25. $where1=strpos($filecontents,"\x00\x21\xF9\x04",$str_loc);
  26. if ($where1 === FALSE) {
  27. break;
  28. } else {
  29. $str_loc=$where1+1;
  30. $where2=strpos($filecontents,"\x00\x2C",$str_loc);
  31. if ($where2 === FALSE) {
  32. break;
  33. } else {
  34. if ($where1+8 == $where2) {
  35. $count++;
  36. }
  37. $str_loc=$where2+1;
  38. }
  39. }
  40. }
  41. if ($count > 1) {
  42. return(true);
  43. } else {
  44. return(false);
  45. }
  46. }
  47. public static function mime($type) {
  48. switch($type) {
  49. case self::JPEG: return "image/jpeg";
  50. case self::PNG: return "image/png";
  51. default: return "image/gif";
  52. }
  53. }
  54. public static function ext($type) {
  55. switch($type) {
  56. case self::JPEG: return "jpg";
  57. case self::PNG: return "png";
  58. default: return "gif";
  59. }
  60. }
  61. public static function func($type) {
  62. switch($type) {
  63. case self::JPEG: return "imagejpeg";
  64. case self::PNG: return "imagepng";
  65. default: return "imagegif";
  66. }
  67. }
  68. /* SQUARE FUNCTION DOES NOT WORK */
  69. public static function Square($im, $clip=true, $noClipBG=array(000,000,000)) {
  70. $w = imagesx($im);
  71. $h = imagesy($im);
  72. if($width < $height) {
  73. return self::ScaleHeight($im, $w, $h, 1, 1, $clip, $noClipBG);
  74. } else {
  75. return self::ScaleWidth($im, $w, $h, 1, 1, $clip, $noClipBG);
  76. }
  77. }
  78. public static function Ratio($im, $w, $h, $clip=true, $noClipBG=array(000,000,000)) {
  79. $width = imagesx($im);
  80. $height = imagesy($im);
  81. if($w > $h) {
  82. return self::ScaleWide($im, $width, $height, $w, $h, $clip, $noClipBG);
  83. } elseif($w == $h) {
  84. return self::Square($im, $clip, $noClipBG);
  85. } else {
  86. return self::ScaleHigh($im, $width, $height, $w, $h, $clip, $noClipBG);
  87. }
  88. }
  89. public static function ScaleWide($im, $w, $h, $r_w, $r_h, $clip, $noClipBG) {
  90. if(($w / $h) < ($r_w / $r_h)) {
  91. return self::ScaleHeight($im, $w, $h, $r_w, $r_h, $clip, $noClipBG);
  92. } else {
  93. return self::ScaleWidth($im, $w, $h, $r_w, $r_h, $clip, $noClipBG);
  94. }
  95. }
  96. public static function ScaleHigh($im, $w, $h, $r_w, $r_h, $clip, $noClipBG) {
  97. if(($w / $h) < ($r_w / $r_h)) {
  98. return self::ScaleHeight($im, $w, $h, $r_w, $r_h, $clip, $noClipBG);
  99. } else {
  100. return self::ScaleWidth($im, $w, $h, $r_w, $r_h, $clip, $noClipBG);
  101. }
  102. }
  103. public static function ScaleHeight($im, $w, $h, $r_w, $r_h, $clip, $noClipBG) {
  104. if($clip) {
  105. $n_width = $w;
  106. $n_height = ($w*$r_h)/$r_w;
  107. $x = 0;
  108. $y = intval(($h - $n_height) / 2);
  109. return self::Crop($im, $x, $y, $n_width, $n_height, $noClipBG);
  110. } else {
  111. $n_height = $h;
  112. $n_width = ($h*$r_w)/$r_h;
  113. return self::ResizeAndPad($im, $n_width, $n_height, $noClipBG);
  114. }
  115. }
  116. public static function ScaleWidth($im, $w, $h, $r_w, $r_h, $clip, $noClipBG) {
  117. if($clip) {
  118. $n_height = $h;
  119. $n_width = ($h*$r_w)/$r_h;
  120. $x = intval(($w - $n_width) / 2);
  121. $y = 0;
  122. return self::Crop($im, $x, $y, $n_height, $n_width, $noClipBG);
  123. } else {
  124. $n_width = $w;
  125. $n_height = ($w*$r_h)/$r_w;
  126. return self::ResizeAndPad($im, $n_width, $n_height, $noClipBG);
  127. }
  128. }
  129. public static function Crop($im, $start_x, $start_y, $run_x, $run_y, $noClipBG) {
  130. $width = imagesx($im);
  131. $height = imagesy($im);
  132. if($start_x > $width) {
  133. $start_x = 0;
  134. }
  135. if($start_y > $height) {
  136. $start_y = 0;
  137. }
  138. if(($start_x + $run_x) > $width) {
  139. $run_x = $width-$start_x;
  140. }
  141. if(($start_y + $run_y) > $height) {
  142. $run_y = $height-$start_y;
  143. }
  144. return self::Resize($im, $run_x, $run_y, $run_x, $run_y, 0, 0, $start_x, $start_y, $bgColor);
  145. }
  146. public static function ResizeAndPad($im, $bounding_w, $bounding_h, $noClipBG) {
  147. $width = imagesx($im);
  148. $height = imagesy($im);
  149. if($bounding_w > $width) {
  150. $x = intval(($bounding_w - $width) / 2);
  151. } else {
  152. $x = 0;
  153. }
  154. if($bounding_h > $height) {
  155. $y = intval(($bounding_h - $height) / 2);
  156. } else {
  157. $y = 0;
  158. }
  159. return self::Pad($im, $bounding_w, $bounding_h, $x, $y, $noClipBG);
  160. }
  161. public static function ScaleToBounding($im, $bounding_w, $bounding_h, $alpha = false) {
  162. $width = imagesx($im);
  163. $height = imagesy($im);
  164. if($width <= $bounding_w AND $height <= $bounding_h) {
  165. return $im;
  166. }
  167. if($bounding_w > $bounding_h) {
  168. if($width > $height) {
  169. $n_width = $bounding_w;
  170. $n_height = intval(($height * $bounding_w) / $width);
  171. } else {
  172. $n_height = $bounding_h;
  173. $n_width = intval(($width * $bounding_h) / $height);
  174. }
  175. } else {
  176. if($width > $height) {
  177. $n_height = $bounding_h;
  178. $n_width = intval(($width * $bounding_h) / $height);
  179. } else {
  180. $n_width = $bounding_w;
  181. $n_height = intval(($height * $bounding_w) / $width);
  182. }
  183. }
  184. if($width < $bounding_w AND $height < $bounding_h) {
  185. $n_width = $width;
  186. $n_height = $height;
  187. }
  188. // Fuck it...maybe one day...in the meantime:
  189. $n_width = $bounding_w;
  190. $n_height = intval(($height * $bounding_w) / $width);
  191. if($alpha) {
  192. return self::ResizeAlpha($im, $n_width, $n_height, $width, $height);
  193. } else {
  194. return self::Resize($im, $n_width, $n_height, $width, $height);
  195. }
  196. }
  197. public static function ScaleToWidth($im, $n_width, $alpha = false) {
  198. $width = imagesx($im);
  199. $height = imagesy($im);
  200. $n_height = intval(($height * $n_width) / $width);
  201. if($alpha) {
  202. return self::ResizeAlpha($im, $n_width, $n_height, $width, $height);
  203. } else {
  204. return self::Resize($im, $n_width, $n_height, $width, $height);
  205. }
  206. }
  207. public static function Resize($im, $w, $h, $o_w, $o_h, $dst_x=0, $dst_y=0, $src_x=0, $src_y=0, $bgColor=array(000,000,000)) {
  208. $image_p = imagecreatetruecolor($w, $h);
  209. $color = imagecolorallocate($image_p, $bgColor[0], $bgColor[1], $bgColor[2]);
  210. imagefill($image_p, 0, 0, $color);
  211. imagecopyresampled($image_p, $im, $dst_x, $dst_y, $src_x, $src_y, $w, $h, $o_w, $o_h);
  212. return $image_p;
  213. }
  214. public static function ResizeAlpha($im, $w, $h, $o_w, $o_h, $dst_x=0, $dst_y=0, $src_x=0, $src_y=0) {
  215. $image_p = imagecreatetruecolor($w, $h);
  216. imagesavealpha($image_p, true);
  217. imagefill($image_p, 0, 0, imagecolorallocatealpha($image_p, 0, 0, 0, 127));
  218. imagecopyresampled($image_p, $im, $dst_x, $dst_y, $src_x, $src_y, $w, $h, $o_w, $o_h);
  219. return $image_p;
  220. }
  221. public static function AddLayer($im, $im2, $x=0, $y=0, $opacity=100) {
  222. if($opacity <= 0) {
  223. return $im;
  224. } elseif($opacity >= 100) {
  225. imagecopy($im, $im2, $x, $y, 0, 0, imagesx($im2), imagesy($im2));
  226. imagedestroy($im2);
  227. return $im;
  228. } else {
  229. imagealphablending($im, true);
  230. imagealphablending($im2, true);
  231. imagecopymerge ($im, $im2, $x, $y, 0, 0, imagesx($im2), imagesy($im2), $opacity);
  232. imagedestroy($im2);
  233. return $im;
  234. }
  235. }
  236. public static function Pad($im, $w, $h, $x, $y, $bgColor) {
  237. $image_p = imagecreatetruecolor($w, $h);
  238. $color = imagecolorallocate($image_p, $bgColor[0], $bgColor[1], $bgColor[2]);
  239. imagefill($image_p, 0, 0, $color);
  240. return self::AddLayer($image_p, $im, $x, $y);
  241. }
  242. public static function Rotate($im, $degrees=90,$bg=0) {
  243. $im = imagerotate($im,$degrees,$bg);
  244. return $im;
  245. }
  246. public static function ZoomAndClipToBounding($im, $w, $h) {
  247. $image_w = imagesx($im);
  248. $image_h = imagesy($im);
  249. if($w > $h) {
  250. if($image_w > $image_h) {
  251. if(($image_h / $image_w) >= ($h / $w)) {
  252. // Both sizes are wide, not tall
  253. // Dest Ratio > Source Ratio
  254. // Set Width, Clip Height
  255. $im = self::ZoomWidthClipHeight($im, $w, $h);
  256. } else {
  257. // Both sizes are wide, not tall
  258. // Source Ratio > Dest Ratio
  259. // Set Height, Clip Width
  260. $im = self::ZoomHeightClipWidth($im, $w, $h);
  261. }
  262. } else {
  263. // Destination is Wide, Source is Long
  264. // Ratio's don't matter in this case
  265. // Set Width, Clip Height
  266. $im = self::ZoomWidthClipHeight($im, $w, $h);
  267. }
  268. } else {
  269. if($image_h > $image_w) {
  270. if(($image_w / $image_h) >= ($w / $h)) {
  271. // Both sizes are tall, not wide
  272. // Source Ratio > Dest Ratio
  273. // Set Height, Clip Width
  274. $im = self::ZoomHeightClipWidth($im, $w, $h);
  275. } else {
  276. // Both sizes are tall, not wide
  277. // Dest Ratio > Source Ratio
  278. // Set Width, Clip Height
  279. $im = self::ZoomWidthClipHeight($im, $w, $h);
  280. }
  281. } else {
  282. // Destination is Tall, Source is Wide
  283. // Ratio's don't matter in this case
  284. // Set Height, Clip Width
  285. $im = self::ZoomHeightClipWidth($im, $w, $h);
  286. }
  287. }
  288. return $im;
  289. }
  290. public static function ZoomHeightClipWidth($im, $w, $h) {
  291. $image_w = imagesx($im);
  292. $image_h = imagesy($im);
  293. $new_h = $h;
  294. $new_w = intval(($image_w * $new_h) / $image_h);
  295. $y = 0;
  296. $x = intval(($new_w - $w) / 2);
  297. $im = self::Resize($im, $new_w, $new_h, $image_w, $image_h);
  298. return self::Resize($im, $w, $h, $w, $h, 0, 0, $x, $y);
  299. }
  300. public static function ZoomWidthClipHeight($im, $w, $h) {
  301. $image_w = imagesx($im);
  302. $image_h = imagesy($im);
  303. $new_w = $w;
  304. $new_h = intval(($image_h * $new_w) / $image_w);
  305. $y = intval(($new_h - $h) / 2);
  306. $x = 0;
  307. $im = self::Resize($im, $new_w, $new_h, $image_w, $image_h);
  308. return self::Resize($im, $w, $h, $w, $h, 0, 0, $x, $y);
  309. }
  310. public static function toString(&$im, $type='jpeg') {
  311. $type = ltrim(rtrim(strtolower($type)));
  312. ob_start();
  313. switch($type) {
  314. case 'gif':
  315. imagegif($im);
  316. break;
  317. case 'png':
  318. imagepng($im);
  319. break;
  320. case 'jpeg':
  321. case 'jpg':
  322. default:
  323. imagejpeg($im, null, 100);
  324. break;
  325. }
  326. $content = ob_get_contents();
  327. ob_end_clean();
  328. return $content;
  329. }
  330. public static function AddLayerAnimation($imageString, $image) {
  331. $prefix = md5($file.time().$_SERVER['REMOTE_ADDR']);
  332. $original = '/tmp/'.$prefix.".original.gif";
  333. $sample = '/tmp/'.$prefix.".sample.png";
  334. $final = '/tmp/'.$prefix.".final.gif";
  335. file_put_contents($original, $imageString);
  336. imagepng($image, $sample);
  337. $cmd = "convert {$original} -draw \"image Over 0,0, 0,0 '{$sample}'\" {$final}";
  338. $x = 0;
  339. $imageString = null;
  340. while(@imagecreatefromstring($imageString) == false) {
  341. exec($cmd, $output);
  342. $imageString = file_get_contents($final);
  343. $x++;
  344. if($x > 20) {
  345. // fuck it.
  346. break;
  347. }
  348. }
  349. unlink($original);
  350. unlink($sample);
  351. unlink($final);
  352. return $imageString;
  353. }
  354. public static function ResizeAnimationToBounding($imageString, $bounding_w, $bounding_h) {
  355. $im = imagecreatefromstring($imageString);
  356. $width = imagesx($im);
  357. $height = imagesy($im);
  358. imagedestroy($im);
  359. if($width > $height) {
  360. $n_width = $bounding_w;
  361. $n_height = intval(($height * $bounding_w) / $width);
  362. } else {
  363. $n_height = $bounding_h;
  364. $n_width = intval(($width * $bounding_h) / $height);
  365. }
  366. if($width < $bounding_w AND $height < $bounding_h) {
  367. $n_width = $width;
  368. $n_height = $height;
  369. }
  370. $prefix = md5($file.rand(0,1000).time().$_SERVER['REMOTE_ADDR']);
  371. $orginal = '/tmp/'.$prefix.".original.gif";
  372. $resized = '/tmp/'.$prefix.".resize.gif";
  373. file_put_contents($orginal, $imageString);
  374. //$cmd = "gifsicle -O -f --resize {$n_width}x{$n_height} {$orginal} > {$resized}";
  375. //exec($cmd." 2>&1", $output);
  376. $cmd = "convert {$orginal} -coalesce -resize {$n_width}x{$n_height} {$resized}";
  377. $x = 0;
  378. $imageString = null;
  379. while(@imagecreatefromstring($imageString) == false) {
  380. exec($cmd, $output);
  381. $imageString = file_get_contents($resized);
  382. $x++;
  383. if($x > 20) {
  384. // fuck it.
  385. break;
  386. }
  387. }
  388. unlink($orginal);
  389. unlink($resized);
  390. return $imageString;
  391. }
  392. } // End Image Helper Class