PageRenderTime 25ms CodeModel.GetById 38ms RepoModel.GetById 0ms app.codeStats 1ms

/subsystems/image.php

https://github.com/oicericbarbosajr/exponent-cms
PHP | 504 lines | 288 code | 65 blank | 151 comment | 89 complexity | 83fd9853b317de49a8f0f52d65f564b2 MD5 | raw file
  1. <?php
  2. ##################################################
  3. #
  4. # Copyright (c) 2004-2006 OIC Group, Inc.
  5. # Written and Designed by James Hunt
  6. #
  7. # This file is part of Exponent
  8. #
  9. # Exponent is free software; you can redistribute
  10. # it and/or modify it under the terms of the GNU
  11. # General Public License as published by the Free
  12. # Software Foundation; either version 2 of the
  13. # License, or (at your option) any later version.
  14. #
  15. # GPL: http://www.gnu.org/licenses/gpl.txt
  16. #
  17. ##################################################
  18. include_once(realpath(dirname(__FILE__).'/../compat/gd_info.php'));
  19. /* exdoc
  20. * The definition of this constant lets other parts of the subsystem know
  21. * that the Image Subsystem has been included for use.
  22. * @node Subsystems:Image
  23. */
  24. define('SYS_IMAGE',1);
  25. define('IMAGE_ERR_NOGD','');
  26. define('IMAGE_ERR_NOTSUPPORTED','_unknown');
  27. define('IMAGE_ERR_FILENOTFOUND','_notfound');
  28. define('IMAGE_ERR_PERMISSIONDENIED','_denied');
  29. /* exdoc
  30. * Output the contents of the fallback preview image.
  31. *
  32. * This is used by the dynamic thumbnail script (/thumb.php)
  33. * if it finds that the server does not have to appropriate GD
  34. * support to generate a specific type of preview (i.e. no GIF support)
  35. * or if GD isn't enabled at all.
  36. *
  37. * @param string $base The base directory of Exponent. Refer to the BASE constant.
  38. * @node Subsystems:Image
  39. */
  40. function exponent_image_showFallbackPreviewImage($base,$error = IMAGE_ERR_NOGD) {
  41. $fh = fopen($base.'subsystems/image/default_preview'.$error.'.gif','rb');
  42. $img = fread($fh,65536);
  43. fclose($fh);
  44. header('Content-type: image/gif');
  45. echo $img;
  46. }
  47. /* exdoc
  48. * Return size and mimetype information about an image file,
  49. * given its path/filename. This is a wrapper around various
  50. * GD functions, to make all implementations work identically.
  51. *
  52. * @param string $filename The path to the file to query.
  53. * @node Subsystems:Image
  54. */
  55. function exponent_image_sizeinfo($filename) {
  56. if (!file_exists($filename)) {
  57. return IMAGE_ERR_FILENOTFOUND;
  58. }
  59. if (!is_readable($filename)) {
  60. return IMAGE_ERR_PERMISSIONDENIED;
  61. }
  62. $sizeinfo = @getimagesize($filename);
  63. if (!isset($sizeinfo['mime'])) {
  64. // In case this implementation of getimagesize
  65. $types = array(
  66. 'jpg'=>'image/jpeg',
  67. 'jpeg'=>'image/jpeg',
  68. 'gif'=>'image/gif',
  69. 'png'=>'image/png'
  70. );
  71. $lowerfile = strtolower($filename);
  72. foreach ($types as $type=>$mime) {
  73. if (substr($lowerfile,-1*strlen($type),strlen($type)) == $type) $sizeinfo['mime'] = $mime;
  74. }
  75. }
  76. return $sizeinfo;
  77. }
  78. /* exdoc
  79. * Create an image resource handle (from GD) for a given filename.
  80. * This is a wrapper around various GD functions, to provide Exponent
  81. * programmers a single point of entry. It also handles situations where
  82. * there is no GD support compiled into the server. (In this case, null is returned).
  83. *
  84. * At this point, the user should have called exponent_image_sizeInfo on the filename
  85. * and verified that the file does indeed exist, and is readable. A safeguard check
  86. * is in place, however.
  87. *
  88. * @param string $filename The path/filename of the image.
  89. * @param Array $sizeinfo Size information (as returned by exponent_image_sizeInfo
  90. * @node Subsystems:Image
  91. */
  92. function exponent_image_createFromFile($filename,$sizeinfo) {
  93. if (!EXPONENT_HAS_GD) {
  94. return null;
  95. }
  96. $info = gd_info();
  97. if ($sizeinfo['mime'] == 'image/jpeg' && $info['JPG Support'] == true) {
  98. $img = imagecreatefromjpeg($filename);
  99. } else if ($sizeinfo['mime'] == 'image/png' && $info['PNG Support'] == true) {
  100. $img = imagecreatefrompng($filename);
  101. } else if ($sizeinfo['mime'] == 'image/gif' && $info['GIF Read Support'] == true) {
  102. $img = imagecreatefromgif($filename);
  103. } else {
  104. // Either we have an unknown image type, or an unsupported image type.
  105. return IMAGE_ERR_NOTSUPPORTED;
  106. }
  107. if (function_exists('imagesavealpha')) {
  108. imagealphablending($img, false);
  109. imagesavealpha($img, true);
  110. }
  111. return $img;
  112. }
  113. /* exdoc
  114. * Create a new blank image resource, with the specified width and height.
  115. * This is a wrapper around various GD functions, to provide Exponent
  116. * programmers a single point of entry. It also handles situations where
  117. * there is no GD support compiled into the server. (In this case, null is returned).
  118. *
  119. * @param integer $w Width of the image resource to create (in pixels)
  120. * @param integer $h Height of the image resource to create (in pixels)
  121. * @node Subsystems:Image
  122. */
  123. function exponent_image_create($w,$h) {
  124. if (!EXPONENT_HAS_GD) {
  125. return null;
  126. }
  127. $info = gd_info();
  128. if (strpos($info['GD Version'],'2.0') !== false) {
  129. $img = imagecreatetruecolor($w,$h);
  130. if (function_exists('imagesavealpha')) {
  131. imagealphablending($img, false);
  132. imagesavealpha($img, true);
  133. }
  134. return $img;
  135. } else {
  136. return imagecreate($w,$h);
  137. }
  138. }
  139. function exponent_image_copyresized($dest,$src,$dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) {
  140. if (!EXPONENT_HAS_GD) {
  141. return null;
  142. }
  143. $info = gd_info();
  144. if (strpos($info['GD Version'],'2.0') !== false) {
  145. return imagecopyresampled($dest,$src,$dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
  146. } else {
  147. return imagecopyresized($dest,$src,$dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
  148. }
  149. }
  150. /* exdoc
  151. * Proportionally scale an image by a specific percentage
  152. * This is a wrapper around various GD functions, to provide Exponent
  153. * programmers a single point of entry. It also handles situations where
  154. * there is no GD support compiled into the server. (In this case, null is returned).
  155. *
  156. * @param string $filename The path/filename of the image to scale.
  157. * @param decimal $scale The scaling factor, as a decimal (i.e. 0.5 for 50%)
  158. * @node Subsystems:Image
  159. */
  160. function exponent_image_scaleByPercent($filename,$scale) {
  161. $sizeinfo = exponent_image_sizeinfo($filename);
  162. if (!is_array($sizeinfo)) {
  163. return $sizeinfo;
  164. }
  165. $original = exponent_image_createFromFile($filename,$sizeinfo);
  166. if (!is_resource($original)) {
  167. return $original;
  168. }
  169. if ($scale == 1) {
  170. return $original;
  171. }
  172. $w = $scale * $sizeinfo[0];
  173. $h = $scale * $sizeinfo[1];
  174. $thumb = exponent_image_create($w,$h);
  175. if (!$thumb) return null;
  176. exponent_image_copyresized($thumb,$original,0,0,0,0,$w,$h,$sizeinfo[0],$sizeinfo[1]);
  177. return $thumb;
  178. }
  179. /* exdoc
  180. * Proportionally scale an image to a given width. Height adjusts accordingly.
  181. * This is a wrapper around various GD functions, to provide Exponent
  182. * programmers a single point of entry. It also handles situations where
  183. * there is no GD support compiled into the server. (In this case, null is returned).
  184. *
  185. * @param string $filename The path/filename of the image to scale.
  186. * @param integer $width The desired width of the scaled image, in pixels.
  187. * @node Subsystems:Image
  188. */
  189. function exponent_image_scaleToWidth($filename,$width) {
  190. $sizeinfo = exponent_image_sizeinfo($filename);
  191. if (!is_array($sizeinfo)) {
  192. return $sizeinfo;
  193. }
  194. $original = exponent_image_createFromFile($filename,$sizeinfo);
  195. if (!is_resource($original)) {
  196. return $sizeinfo;
  197. }
  198. if ($width == $sizeinfo[0]) {
  199. return $original;
  200. }
  201. $w = $width;
  202. $h = ($width / $sizeinfo[0]) * $sizeinfo[1];
  203. $thumb = exponent_image_create($w,$h);
  204. if (!$thumb) return null;
  205. exponent_image_copyresized($thumb,$original,0,0,0,0,$w,$h,$sizeinfo[0],$sizeinfo[1]);
  206. return $thumb;
  207. }
  208. /* exdoc
  209. * Proportionally scale an image to a given height. Width adjusts accordingly.
  210. * This is a wrapper around various GD functions, to provide Exponent
  211. * programmers a single point of entry. It also handles situations where
  212. * there is no GD support compiled into the server. (In this case, null is returned).
  213. *
  214. * @param string $filename The path/filename of the image to scale.
  215. * @param integer $height The desired height of the scaled image, in pixels.
  216. * @node Subsystems:Image
  217. */function exponent_image_scaleToHeight($filename,$height) {
  218. $sizeinfo = exponent_image_sizeinfo($filename);
  219. if (!is_array($sizeinfo)) {
  220. return $sizeinfo;
  221. }
  222. $original = exponent_image_createFromFile($filename,$sizeinfo);
  223. if (!is_resource($original)) {
  224. return $original;
  225. }
  226. if ($height == $sizeinfo[1]) {
  227. return $original;
  228. }
  229. $w = ($height / $sizeinfo[1]) * $sizeinfo[0];
  230. $h = $height;
  231. $thumb = exponent_image_create($w,$h);
  232. if (!$thumb) return null;
  233. exponent_image_copyresized($thumb,$original,0,0,0,0,$w,$h,$sizeinfo[0],$sizeinfo[1]);
  234. return $thumb;
  235. }
  236. /* exdoc
  237. * Proportionally scale an image to fit within the given width / height.
  238. * This is a wrapper around various GD functions, to provide Exponent
  239. * programmers a single point of entry. It also handles situations where
  240. * there is no GD support compiled into the server. (In this case, null is returned).
  241. *
  242. * @param string $filename The path/filename of the image to scale.
  243. * @param integer $width The maximum width of the scaled image, in pixels.
  244. * @param integer $height The maximum height of the scaled image, in pixels.
  245. * @node Subsystems:Image
  246. */
  247. function exponent_image_scaleToConstraint($filename,$width,$height) {
  248. $sizeinfo = exponent_image_sizeinfo($filename);
  249. if (!is_array($sizeinfo)) {
  250. return $sizeinfo;
  251. }
  252. $original = exponent_image_createFromFile($filename,$sizeinfo);
  253. if (!is_resource($original)) {
  254. return $original;
  255. }
  256. if ($width >= $sizeinfo[0] && $height >= $sizeinfo[1]) {
  257. return $original;
  258. }
  259. $w = $width;
  260. $h = ($width / $sizeinfo[0]) * $sizeinfo[1];
  261. if ($h > $height) { // height is outside
  262. $w = ($height / $sizeinfo[1]) * $sizeinfo[0];
  263. $h = $height;
  264. }
  265. $thumb = exponent_image_create($w,$h);
  266. if (!$thumb) return null;
  267. exponent_image_copyresized($thumb,$original,0,0,0,0,$w,$h,$sizeinfo[0],$sizeinfo[1]);
  268. return $thumb;
  269. }
  270. /* exdoc
  271. * Scale an image to a square keeping the image aspect ratio.
  272. * If the image is smaller in either dimension than request square side original is returned.
  273. * Image is first cropped to a square of length smaller of width or height and then resized.
  274. * This is a wrapper around various GD functions, to provide Exponent
  275. * programmers a single point of entry. It also handles situations where
  276. * there is no GD support compiled into the server. (In this case, null is returned).
  277. *
  278. * @param string $filename The path/filename of the image to scale.
  279. * @param integer $size The desired side length of the scaled image, in pixels.
  280. * @node Subsystems:Image
  281. */
  282. function exponent_image_scaleToSquare($filename,$side) {
  283. $sizeinfo = exponent_image_sizeinfo($filename);
  284. if (!is_array($sizeinfo)) {
  285. return $sizeinfo;
  286. }
  287. $original = exponent_image_createFromFile($filename,$sizeinfo);
  288. if (!is_resource($original)) {
  289. return $original;
  290. }
  291. if ($side >= $sizeinfo[0] || $side >= $sizeinfo[1]) {
  292. return $original;
  293. }
  294. /* The defaults will serve in case the image is a square */
  295. $src_x = 0;
  296. $src_y = 0;
  297. $width = $sizeinfo[0];
  298. $height = $sizeinfo[1];
  299. /*if width greater than height, we crop the image left and right */
  300. if ($sizeinfo[0] > $sizeinfo[1]) {
  301. $width=$sizeinfo[1];
  302. $height=$sizeinfo[1];
  303. $src_x=round(($sizeinfo[0]-$width)/2,0);
  304. }
  305. else
  306. {
  307. /*if height greater than width, we crop the image top and bottom */
  308. $height=$sizeinfo[0];
  309. $width=$sizeinfo[0];
  310. $src_y=round(($sizeinfo[1]-$height)/2,0);
  311. }
  312. $w = $side;
  313. $h = $side;
  314. $thumb = exponent_image_create($w,$h);
  315. if (!$thumb) return null;
  316. exponent_image_copyresized($thumb,$original,0,0,$src_x,$src_y,$w,$h,$width,$height);
  317. return $thumb;
  318. }
  319. /* exdoc
  320. * Scale an image to a given width and height, without regard to aspect ratio.
  321. * This is a wrapper around various GD functions, to provide Exponent
  322. * programmers a single point of entry. It also handles situations where
  323. * there is no GD support compiled into the server. (In this case, null is returned).
  324. *
  325. * @param string $filename The path/filename of the image to scale.
  326. * @param integer $width The desired width of the scaled image, in pixels.
  327. * @param integer $height The desired height of the scaled image, in pixels.
  328. * @node Subsystems:Image
  329. */
  330. function exponent_image_scaleManually($filename,$width,$height) {
  331. $sizeinfo = exponent_image_sizeinfo($filename);
  332. if (!is_array($sizeinfo)) {
  333. return $sizeinfo;
  334. }
  335. $original = exponent_image_createFromFile($filename,$sizeinfo);
  336. if (!is_resource($original)) {
  337. return $original;
  338. }
  339. if ($width == $sizeinfo[0] && $height == $sizeinfo[1]) {
  340. return $original;
  341. }
  342. $thumb = exponent_image_create($width,$height);
  343. if (!$thumb) return null;
  344. exponent_image_copyresized($thumb,$original,0,0,0,0,$width,$height,$sizeinfo[0],$sizeinfo[1]);
  345. return $thumb;
  346. }
  347. function exponent_image_rotate($filename,$degrees) {
  348. $sizeinfo = exponent_image_sizeinfo($filename);
  349. if (!is_array($sizeinfo)) {
  350. return $sizeinfo;
  351. }
  352. $original = exponent_image_createFromFile($filename,$sizeinfo);
  353. if (!is_resource($original)) {
  354. return $original;
  355. }
  356. $color = imagecolorclosesthwb($original,255,255,255);
  357. return imagerotate($original,$degrees,$color);
  358. }
  359. function exponent_image_flip($filename,$is_horizontal) {
  360. $sizeinfo = exponent_image_sizeinfo($filename);
  361. if (!is_array($sizeinfo)) {
  362. return $sizeinfo;
  363. }
  364. $original = exponent_image_createFromFile($filename,$sizeinfo);
  365. if (!is_resource($original)) {
  366. return $original;
  367. }
  368. // Horizontal - invert y coords
  369. // Vertical - invert x coords
  370. $w = $sizeinfo[0];
  371. $h = $sizeinfo[1];
  372. $new = exponent_image_create($w,$h);
  373. if ($is_horizontal) {
  374. // Copy column by column
  375. //$dest,$src,$dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) {
  376. for ($i = 0; $i < $w; $i++) {
  377. imagecopy($new,$original, // DESTINATION, SOURCE
  378. $i,0, // dst_X, dst_Y
  379. $w-$i-1,0, // src_X,src_Y
  380. 1,$h); //src_W, src_H
  381. }
  382. } else {
  383. // Copy row by row.
  384. //$dest,$src,$dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) {
  385. for ($i = 0; $i < $h; $i++) {
  386. imagecopy($new,$original, // DESTINATION, SOURCE
  387. 0,$i, // dst_X, dst_Y
  388. 0,$h-$i-1, // src_X,src_Y
  389. #$w,1, // dst_W, dst_H
  390. $w,1); //src_W, src_H
  391. }
  392. }
  393. return $new;
  394. }
  395. /* exdoc
  396. * @state <b>UNDOCUMENTED</b>
  397. * @node Undocumented
  398. */
  399. function exponent_image_output($img, $sizeinfo, $filename=null, $quality=75) {
  400. header('Content-type: ' . $sizeinfo['mime']);
  401. if ($sizeinfo['mime'] == 'image/jpeg') {
  402. ($filename != null) ? imagejpeg($img, $filename, $quality) : imagejpeg($img, null, $quality);
  403. } else if ($sizeinfo['mime'] == 'image/png') {
  404. ($filename != null) ? imagepng($img,$filename) : imagepng($img);
  405. } else if ($sizeinfo['mime'] == 'image/gif') {
  406. ($filename != null) ? imagepng($img,$filename) : imagepng($img);
  407. }
  408. }
  409. /* exdoc
  410. * @state <b>UNDOCUMENTED</b>
  411. * @node Undocumented
  412. */
  413. function exponent_image_captcha($w,$h,$string) {
  414. $img = exponent_image_create($w,$h);
  415. if ($img) {
  416. // We were able to create an image.
  417. $bg = imagecolorallocate($img,250,255,225);
  418. imagefill($img,0,0,$bg);
  419. #echo $bg;
  420. $colors = array();
  421. for ($i = 0; $i < strlen($string) && $i < 10; $i++) {
  422. $colors[$i] = imagecolorallocate($img,rand(50,150),rand(50,150),rand(50,150));
  423. }
  424. $px_per_char = floor($w / (strlen($string)+1));
  425. for ($i = 0; $i < strlen($string); $i++) {
  426. imagestring($img,rand(4,6),$px_per_char * ($i+1) + rand(-5,5),rand(0,$h / 2),$string{$i},$colors[($i % 10)]);
  427. }
  428. // Need this to be 'configurable'
  429. for ($i = 0; $i < strlen($string) / 2 && $i < 10; $i++) {
  430. $c = imagecolorallocate($img,rand(150,250),rand(150,250),rand(150,250));
  431. imageline($img,rand(0,$w / 4),rand(5, $h-5),rand(3*$w / 4,$w),rand(0,$h),$c);
  432. }
  433. //imagestring($img,6,0,0,$string,$color);
  434. return $img;
  435. } else {
  436. return null;
  437. }
  438. }
  439. ?>