PageRenderTime 38ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/library/simplegd/classes/SimpleGdImage.class.old.php

https://github.com/fb83/Project-Pier
PHP | 549 lines | 273 code | 56 blank | 220 comment | 59 complexity | 1567a95b2c373e5f3e89059fc652e287 MD5 | raw file
Possible License(s): AGPL-1.0, GPL-2.0, AGPL-3.0, LGPL-2.1, GPL-3.0
  1. <?php
  2. /**
  3. * SimpleGdImage wraps arround GD image resource and provides methods to work
  4. * with the resource as with a single object
  5. *
  6. * @version 1.0
  7. * @http://www.projectpier.org/
  8. */
  9. class SimpleGdImage {
  10. /** Boundaries **/
  11. const BOUNDARY_INCREASE_ONLY = 'increase';
  12. const BOUNDARY_DECREASE_ONLY = 'decrease';
  13. /**
  14. * Is new flag, true if we created this image from resouce, not from file
  15. * and we didn't save it to the file
  16. *
  17. * @var boolean
  18. */
  19. protected $is_new = true;
  20. /**
  21. * Is loaded flag, true if loaded this file from the file (or saved it to the file)
  22. *
  23. * @var string
  24. */
  25. protected $is_loaded = false;
  26. /**
  27. * Image resouce
  28. *
  29. * @var resouce
  30. */
  31. protected $resource;
  32. /**
  33. * Original file path
  34. *
  35. * @var string
  36. */
  37. protected $source;
  38. /**
  39. * Image type
  40. *
  41. * @var integer
  42. */
  43. protected $image_type;
  44. /**
  45. * Image width, cached on request
  46. *
  47. * @var integer
  48. */
  49. protected $width = null;
  50. /**
  51. * Image height, cached on request
  52. *
  53. * @var integer
  54. */
  55. protected $height = null;
  56. /**
  57. * Construct new SimpleGdImage object
  58. *
  59. * @param string $load_from_file Load content from image file
  60. * @return SimpleGdImage
  61. */
  62. function __construct($load_from_file = null) {
  63. if (!is_null($load_from_file)) {
  64. $this->loadFromFile($load_from_file);
  65. }
  66. } // __construct
  67. /**
  68. * Destroy this object and free any memory associated with image image
  69. *
  70. * @param void
  71. * @return null
  72. */
  73. function __destruct() {
  74. if (is_resource($this->resource)) {
  75. imagedestroy($this->resource);
  76. }
  77. } // __destruct
  78. // ---------------------------------------------------
  79. // Utils
  80. // ---------------------------------------------------
  81. /**
  82. * Load this image from file
  83. *
  84. * @param string $file_path
  85. * @return null
  86. */
  87. function loadFromFile($file_path) {
  88. if (!is_readable($file_path)) {
  89. throw new FileDnxError($file_path);
  90. }
  91. $image_type = false;
  92. if (function_exists('exif_imagetype')) {
  93. $image_type = exif_imagetype($file_path);
  94. } else {
  95. $image_size = getimagesize($file_path);
  96. if (is_array($image_size) && isset($image_size[2])) {
  97. $image_type = $image_size[2];
  98. }
  99. } // if
  100. if ($image_type === false) {
  101. throw new FileNotImageError($file_path);
  102. }
  103. switch ($image_type) {
  104. case IMAGETYPE_PNG:
  105. $this->resource = imagecreatefrompng($file_path);
  106. break;
  107. case IMAGETYPE_JPEG:
  108. $this->resource = imagecreatefromjpeg($file_path);
  109. break;
  110. case IMAGETYPE_GIF:
  111. $this->resource = imagecreatefromgif($file_path);
  112. break;
  113. default:
  114. throw new ImageTypeNotSupportedError($file_path, $image_type);
  115. } // switch
  116. if (!is_resource($this->resource)) {
  117. $this->resource = null;
  118. throw new FailedToLoadImageError($file_path);
  119. } // if
  120. $this->setIsLoaded();
  121. $this->setSource($file_path);
  122. $this->setImageType($image_type);
  123. } // loadFromFile
  124. /**
  125. * This function is used for saving files that are loaded to file in case
  126. * you transformed the resource and want to save it back to the file. If
  127. * this file is new or you want to change its type use saveAs() function
  128. *
  129. * @param void
  130. * @return boolean
  131. * @throws ImageTypeNotSupportedError
  132. * @throws FileNotWriableError
  133. */
  134. function save() {
  135. if (!$this->isLoaded() || !is_file($this->getSource())) {
  136. throw new Error('This image was not loaded from the file. Use saveAs() function instead of save() - there you\'ll be able to specify output file and type');
  137. } // if
  138. if (!file_is_writable($this->getSource())) {
  139. throw new FileNotWriableError($this->getSource());
  140. } // if
  141. switch ($this->getImageType()) {
  142. case IMAGETYPE_PNG:
  143. imagepng($this->resource, $this->getSource());
  144. break;
  145. case IMAGETYPE_JPG:
  146. imagejpeg($this->resource, $this->getSource(), 80);
  147. break;
  148. case IMAGETYPE_GIF:
  149. imagegif($this->resource, $this->getSource());
  150. break;
  151. default:
  152. throw new ImageTypeNotSupportedError(null, $this->getImageType());
  153. } // switch
  154. return true;
  155. } // save
  156. /**
  157. * Save image into the file
  158. *
  159. * @param string $file_path
  160. * @param integer $as_type Save image as type. Default type is PNG
  161. * @return null
  162. * @throws ImageTypeNotSupportedError
  163. * @throws FailedToWriteFileError
  164. */
  165. function saveAs($file_path, $as_type = null) {
  166. // Use internal value if we called convertType with new object
  167. if (is_null($as_type)) {
  168. $as_type = $this->getImageType();
  169. }
  170. $as_type = (integer) $as_type;
  171. if (($as_type < IMAGETYPE_GIF) || ($as_type > IMAGETYPE_PNG)) {
  172. $as_type = IMAGETYPE_PNG;
  173. }
  174. switch ($as_type) {
  175. case IMAGETYPE_PNG:
  176. $write = imagepng($this->resource, $file_path);
  177. break;
  178. case IMAGETYPE_JPEG:
  179. $write = imagejpeg($this->resource, $file_path, 80);
  180. break;
  181. case IMAGETYPE_GIF:
  182. $write = imagegif($this->resource, $file_path);
  183. break;
  184. default:
  185. throw new ImageTypeNotSupportedError(null, $this->getImageType());
  186. } // switch
  187. if (!$write) {
  188. throw new FailedToWriteFileError($file_path);
  189. }
  190. return true;
  191. } // saveAs
  192. /**
  193. * User image resource to populate this object
  194. *
  195. * @param resource $resource
  196. * @return null
  197. */
  198. function createFromResource($resource) {
  199. if (is_resource($resource) && (get_resource_type($resource) == 'gd')) {
  200. $this->reset();
  201. $this->resource = $resource;
  202. } else {
  203. throw new InvalidInstanceError('resource', $resource, 'resource');
  204. } // if
  205. } // createFromResource
  206. /**
  207. * Reset all fields
  208. *
  209. * @param void
  210. * @return null
  211. */
  212. protected function reset() {
  213. $this->is_new = true;
  214. $this->is_loaded = false;
  215. $this->resource = null;
  216. $this->source = null;
  217. $this->image_type = null;
  218. $this->width = null;
  219. $this->height = null;
  220. } // reset
  221. /**
  222. * Return MIME type based on image type
  223. *
  224. * @param void
  225. * @return string
  226. */
  227. function getMimeType() {
  228. return image_type_to_mime_type($this->getImageType());
  229. } // getMimeType
  230. /**
  231. * Return extension based on the source file or type if we have new image
  232. *
  233. * @param void
  234. * @return string
  235. */
  236. function getExtension() {
  237. if ($this->isLoaded()) {
  238. return get_file_extension($this->getSource());
  239. } else {
  240. return image_type_to_extension($this->getImageType());
  241. } // if
  242. } // getExtension
  243. // ---------------------------------------------------
  244. // Transformations
  245. // ---------------------------------------------------
  246. /**
  247. * Resize image to given dimensions. This transformation will not keep
  248. * the ratio of the image
  249. *
  250. * @param integer $width New width
  251. * @param integer $height
  252. * @param boolean $mutate If true transofrmation will be done with the internal
  253. * resource. If false new resouce will be created, new SimpleGdImage will be
  254. * created from it and returned
  255. * @return boolean
  256. */
  257. function resize($width, $height, $mutate = true) {
  258. if (!is_resource($this->resource) || (get_resource_type($this->resource) <> 'gd')) {
  259. return false;
  260. }
  261. $width = (integer) $width > 0 ? (integer) $width : 1;
  262. $height = (integer) $height > 0 ? (integer) $height : 1;
  263. if ($this->getImageType() == IMAGETYPE_GIF) {
  264. $new_resource = imagecreatetruecolor($new_width, $new_height);
  265. $colorcount = imagecolorstotal($this->resource);
  266. imagetruecolortopalette($new_resource, true, $colorcount);
  267. imagepalettecopy($new_resource, $this->resource);
  268. $transparentcolor = imagecolortransparent($this->resource);
  269. imagefill($new_resource, 0, 0, $transparentcolor);
  270. imagecolortransparent($new_resource, $transparentcolor);
  271. } else {
  272. $new_resource = imagecreatetruecolor($width, $height);
  273. } // if
  274. imagecopyresampled($new_resource, $this->resource, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
  275. if ($mutate) {
  276. // Destroy old resrouce, set new one and reset cached values
  277. imagedestroy($this->resource);
  278. $this->resource = $new_resource;
  279. $this->width = $width;
  280. $this->height = $height;
  281. return true;
  282. } else {
  283. // Create new image from the resouce and return
  284. $new_image = new SimpleGdImage();
  285. $new_image->createFromResource($new_resource);
  286. return $new_image;
  287. } // if
  288. } // resize
  289. /**
  290. * Resize to $width x $height but keep the image proportion
  291. *
  292. * @param integer $width Max width
  293. * @param integer $height Max height
  294. * @param string $boundary Limit the scale action: drecrease or increase
  295. * only. If $boundary is NULL than don't limit
  296. * @param boolean $mutate Save the transformation in internal resource or
  297. * create new image and keep internal as is?
  298. * @return SimpleGdImage
  299. */
  300. function scale($width, $height, $boundary = null, $mutate = true) {
  301. if (!is_resource($this->resource) || (get_resource_type($this->resource) <> 'gd')) {
  302. return false;
  303. }
  304. $width = (integer) $width > 0 ? (integer) $width : 1;
  305. $height = (integer) $height > 0 ? (integer) $height : 1;
  306. $scale = min($width / $this->getWidth(), $height / $this->getHeight());
  307. if ($boundary == self::BOUNDARY_DECREASE_ONLY) {
  308. if ($scale > 1) {
  309. if ($mutate) {
  310. return;
  311. } else {
  312. $new_image = new SimpleGdImage();
  313. $new_image->createFromResource($this->resource);
  314. return $new_image;
  315. } // if
  316. } // if
  317. } elseif ($boundary == self::BOUNDARY_INCREASE_ONLY) {
  318. if ($scale < 1) {
  319. if ($mutate) {
  320. return;
  321. } else {
  322. $new_image = new SimpleGdImage();
  323. $new_image->createFromResource($this->resource);
  324. return $new_image;
  325. } // if
  326. } // if
  327. } // if
  328. $new_width = floor($scale * $this->getWidth());
  329. $new_height = floor($scale * $this->getHeight());
  330. if ($this->getImageType() == IMAGETYPE_GIF) {
  331. $new_resource = imagecreatetruecolor($new_width, $new_height);
  332. $colorcount = imagecolorstotal($this->resource);
  333. imagetruecolortopalette($new_resource, true, $colorcount);
  334. imagepalettecopy($new_resource, $this->resource);
  335. $transparentcolor = imagecolortransparent($this->resource);
  336. imagefill($new_resource, 0, 0, $transparentcolor);
  337. imagecolortransparent($new_resource, $transparentcolor);
  338. } else {
  339. $new_resource = imagecreatetruecolor($new_width, $new_height);
  340. } // if
  341. imagecopyresampled($new_resource, $this->resource, 0, 0, 0, 0, $new_width, $new_height, $this->getWidth(), $this->getHeight());
  342. if ($mutate) {
  343. imagedestroy($this->resource);
  344. $this->resource = $new_resource;
  345. $this->width = $new_width;
  346. $this->height = $new_height;
  347. return true;
  348. } else {
  349. $new_image = new SimpleGdImage();
  350. $new_image->createFromResource($new_resource);
  351. return $new_image;
  352. } // if
  353. } // scale
  354. /**
  355. * Change internat type value
  356. *
  357. * @param integer $to_type
  358. * @return null
  359. */
  360. function convertType($to_type) {
  361. if ($this->getImageType() == $to_type) {
  362. return;
  363. }
  364. if ($to_type == IMAGETYPE_PNG || $to_type == IMAGETYPE_JPEG || $to_type == IMAGETYPE_GIF) {
  365. $this->setImageType($to_type);
  366. } else {
  367. throw new ImageTypeNotSupportedError(null, $to_type);
  368. } // if
  369. } // convertType
  370. // ---------------------------------------------------
  371. // Flags
  372. // ---------------------------------------------------
  373. /**
  374. * Returns true if this image is new (no file, just resource that we can manipulate)
  375. *
  376. * @param void
  377. * @return boolean
  378. */
  379. function isNew() {
  380. return $this->is_new;
  381. } // isNew
  382. /**
  383. * Returns true if this image is loaded
  384. *
  385. * @param void
  386. * @return boolean
  387. */
  388. function isLoaded() {
  389. return $this->is_loaded;
  390. } // isLoaded
  391. // ---------------------------------------------------
  392. // Getters and setters
  393. // ---------------------------------------------------
  394. /**
  395. * Mark this object as new
  396. *
  397. * @param void
  398. * @return null
  399. */
  400. function setIsNew() {
  401. $this->is_new = true;
  402. $this->is_loaded = false;
  403. } // setIsNew
  404. /**
  405. * Mark this object as loaded
  406. *
  407. * @param void
  408. * @return null
  409. */
  410. function setIsLoaded() {
  411. $this->is_new = false;
  412. $this->is_loaded = true;
  413. } // setIsLoaded
  414. /**
  415. * Get source
  416. *
  417. * @param null
  418. * @return string
  419. */
  420. function getSource() {
  421. return $this->source;
  422. } // getSource
  423. /**
  424. * Set source value
  425. *
  426. * @param string $value
  427. * @return null
  428. */
  429. private function setSource($value) {
  430. $this->source = $value;
  431. } // setSource
  432. /**
  433. * Get image_type
  434. *
  435. * @param null
  436. * @return integer
  437. */
  438. function getImageType() {
  439. return $this->image_type;
  440. } // getImageType
  441. /**
  442. * Set image_type value
  443. *
  444. * @param integer $value
  445. * @return null
  446. */
  447. private function setImageType($value) {
  448. $this->image_type = $value;
  449. } // setImageType
  450. /**
  451. * Get width
  452. *
  453. * @param null
  454. * @return integer
  455. */
  456. function getWidth() {
  457. if (is_null($this->width)) {
  458. $this->width = imagesx($this->resource);
  459. }
  460. return $this->width;
  461. } // getWidth
  462. /**
  463. * Set width value
  464. *
  465. * @param integer $value
  466. * @return null
  467. */
  468. protected function setWidth($value) {
  469. $this->width = $value;
  470. } // setWidth
  471. /**
  472. * Get height
  473. *
  474. * @param null
  475. * @return integer
  476. */
  477. function getHeight() {
  478. if (is_null($this->height)) {
  479. $this->height = imagesy($this->resource);
  480. }
  481. return $this->height;
  482. } // getHeight
  483. /**
  484. * Set height value
  485. *
  486. * @param integer $value
  487. * @return null
  488. */
  489. protected function setHeight($value) {
  490. $this->height = $value;
  491. } // setHeight
  492. } // SimpleGdImage
  493. ?>