PageRenderTime 85ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/fuel/core/classes/image/driver.php

https://bitbucket.org/sriedel/iccrm-wip
PHP | 869 lines | 561 code | 60 blank | 248 comment | 73 complexity | ab77fdc4e63cbaaac44575dfd7e56e84 MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. /**
  3. * Part of the Fuel framework.
  4. *
  5. * Image manipulation class.
  6. *
  7. * @package Fuel
  8. * @version 1.0
  9. * @license MIT License
  10. * @copyright 2010 - 2011 Fuel Development Team
  11. * @link http://fuelphp.com
  12. */
  13. namespace Fuel\Core;
  14. abstract class Image_Driver
  15. {
  16. protected $image_fullpath = null;
  17. protected $image_directory = null;
  18. protected $image_filename = null;
  19. protected $image_extension = null;
  20. protected $new_extension = null;
  21. protected $config = array();
  22. protected $queued_actions = array();
  23. protected $accepted_extensions;
  24. public function __construct($config)
  25. {
  26. \Config::load('image', true);
  27. if (is_array($config))
  28. {
  29. $this->config = array_merge(\Config::get('image'), $config);
  30. }
  31. else
  32. {
  33. $this->config = \Config::get('image');
  34. }
  35. $this->debug("Image Class was initialized using the " . $this->config['driver'] . " driver.");
  36. }
  37. /**
  38. * Accepts configuration in either an array (as $index) or a pairing using $index and $value
  39. *
  40. * @param string $index The index to be set, or an array of configuration options.
  41. * @param mixed $value The value to be set if $index is not an array.
  42. * @return Image_Driver
  43. */
  44. public function config($index = null, $value = null)
  45. {
  46. if (is_array($index))
  47. {
  48. if (isset($index['driver']))
  49. {
  50. throw new \RuntimeException("The driver cannot be changed after initialization!");
  51. }
  52. $this->config = array_merge($this->config, $index);
  53. }
  54. elseif ($index != null)
  55. {
  56. if ($index == 'driver')
  57. {
  58. throw new \RuntimeException("The driver cannot be changed after initialization!");
  59. }
  60. $this->config[$index] = $value;
  61. }
  62. return $this;
  63. }
  64. /**
  65. * Exectues the presets set in the config. Additional parameters replace the $1, $2, ect.
  66. *
  67. * @param string $name The name of the preset.
  68. * @return Image_Driver
  69. */
  70. public function preset($name)
  71. {
  72. $vars = func_get_args();
  73. if (isset($this->config['presets'][$name]))
  74. {
  75. $old_config = $this->config;
  76. $this->config = array_merge($this->config, $this->config['presets'][$name]);
  77. foreach ($this->config['actions'] AS $action)
  78. {
  79. $func = $action[0];
  80. array_shift($action);
  81. for ($i = 0; $i < count($action); $i++)
  82. {
  83. for ($x = count($vars) - 1; $x >= 0; $x--)
  84. {
  85. $action[$i] = preg_replace('#\$' . $x . '#', $vars[$x], $action[$i]);
  86. }
  87. }
  88. call_user_func_array(array($this, $func), $action);
  89. }
  90. $this->config = $old_config;
  91. }
  92. else
  93. {
  94. throw new \InvalidArgumentException("Could not load preset $name, you sure it exists?");
  95. }
  96. return $this;
  97. }
  98. /**
  99. * Loads the image and checks if its compatible.
  100. *
  101. * @param string $filename The file to load
  102. * @param string $return_data Decides if it should return the images data, or just "$this".
  103. * @param mixed $force_extension Decides if it should force the extension witht this (or false)
  104. * @return Image_Driver
  105. */
  106. public function load($filename, $return_data = false, $force_extension = false)
  107. {
  108. // First check if the filename exists
  109. $filename = realpath($filename);
  110. $return = array(
  111. 'filename' => $filename,
  112. 'return_data' => $return_data
  113. );
  114. if (file_exists($filename))
  115. {
  116. // Check the extension
  117. $ext = $this->check_extension($filename, false, $force_extension);
  118. if ($ext !== false)
  119. {
  120. $return = array_merge($return, array(
  121. 'image_fullpath' => $filename,
  122. 'image_directory' => dirname($filename),
  123. 'image_filename' => basename($filename),
  124. 'image_extension' => $ext
  125. ));
  126. if ( ! $return_data)
  127. {
  128. $this->image_fullpath = $filename;
  129. $this->image_directory = dirname($filename);
  130. $this->image_filename = basename($filename);
  131. $this->image_extension = $ext;
  132. }
  133. }
  134. else
  135. {
  136. throw new \RuntimeException("The library does not support this filetype for $filename.");
  137. }
  138. }
  139. else
  140. {
  141. throw new \OutOfBoundsException("Image file $filename does not exist.");
  142. }
  143. return $return;
  144. }
  145. /**
  146. * Crops the image using coordinates or percentages.
  147. *
  148. * Positive whole numbers or percentages are coordinates from the top left.
  149. *
  150. * Negative whole numbers or percentages are coordinates from the bottom right.
  151. *
  152. * @param integer $x1 X-Coordinate for first set.
  153. * @param integer $y1 Y-Coordinate for first set.
  154. * @param integer $x2 X-Coordinate for second set.
  155. * @param integer $y2 Y-Coordinate for second set.
  156. * @return Image_Driver
  157. */
  158. public function crop($x1, $y1, $x2, $y2)
  159. {
  160. $this->queue('crop', $x1, $y1, $x2, $y2);
  161. return $this;
  162. }
  163. /**
  164. * Executes the crop event when the queue is ran.
  165. *
  166. * Formats the crop method input for use with driver specific methods
  167. *
  168. * @param integer $x1 X-Coordinate for first set.
  169. * @param integer $y1 Y-Coordinate for first set.
  170. * @param integer $x2 X-Coordinate for second set.
  171. * @param integer $y2 Y-Coordinate for second set.
  172. * @return array An array of variables for the specific driver.
  173. */
  174. protected function _crop($x1, $y1, $x2, $y2)
  175. {
  176. $y1 === null and $y1 = $x1;
  177. $x2 === null and $x2 = "-" . $x1;
  178. $y2 === null and $y2 = "-" . $y1;
  179. $x1 = $this->convert_number($x1, true);
  180. $y1 = $this->convert_number($y1, false);
  181. $x2 = $this->convert_number($x2, true);
  182. $y2 = $this->convert_number($y2, false);
  183. return array(
  184. 'x1' => $x1,
  185. 'y1' => $y1,
  186. 'x2' => $x2,
  187. 'y2' => $y2
  188. );
  189. }
  190. /**
  191. * Resizes the image. If the width or height is null, it will resize retaining the original aspect ratio.
  192. *
  193. * @param integer $width The new width of the image.
  194. * @param integer $height The new height of the image.
  195. * @param boolean $keepar If false, allows stretching of the image.
  196. * @param boolean $pad Adds padding to the image when resizing.
  197. * @return Image_Driver
  198. */
  199. public function resize($width, $height = null, $keepar = true, $pad = false)
  200. {
  201. $this->queue('resize', $width, $height, $keepar, $pad);
  202. return $this;
  203. }
  204. /**
  205. * Executes the resize event when the queue is ran.
  206. *
  207. * Formats the resize method input for use with driver specific methods.
  208. *
  209. * @param integer $width The new width of the image.
  210. * @param integer $height The new height of the image.
  211. * @param boolean $keepar If false, allows stretching of the image.
  212. * @param boolean $pad Adds padding to the image when resizing.
  213. * @return array An array of variables for the specific driver.
  214. */
  215. protected function _resize($width, $height = null, $keepar = true, $pad = true)
  216. {
  217. if ($height == null or $width == null)
  218. {
  219. if ($height == null and substr($width, -1) == '%')
  220. {
  221. $height = $width;
  222. }
  223. elseif (substr($height, -1) == '%' and $width == null)
  224. {
  225. $width = $height;
  226. }
  227. else
  228. {
  229. $sizes = $this->sizes();
  230. if ($height == null and $width != null)
  231. {
  232. $height = $width * ($sizes->height / $sizes->width);
  233. }
  234. elseif ($height != null and $width == null)
  235. {
  236. $width = $height * ($sizes->width / $sizes->height);
  237. }
  238. else
  239. {
  240. throw new \InvalidArgumentException("Width and height cannot be null.");
  241. }
  242. }
  243. }
  244. $origwidth = $this->convert_number($width, true);
  245. $origheight = $this->convert_number($height, false);
  246. $width = $origwidth;
  247. $height = $origheight;
  248. $sizes = $this->sizes();
  249. $x = 0;
  250. $y = 0;
  251. if ($keepar)
  252. {
  253. // See which is the biggest ratio
  254. if (function_exists('bcdiv'))
  255. {
  256. $width_ratio = bcdiv((float) $width, $sizes->width, 10);
  257. $height_ratio = bcdiv((float) $height, $sizes->height, 10);
  258. $compare = bccomp($width_ratio, $height_ratio, 10);
  259. if ($compare > -1)
  260. {
  261. $height = ceil((float) bcmul($sizes->height, $height_ratio, 10));
  262. $width = ceil((float) bcmul($sizes->width, $height_ratio, 10));
  263. }
  264. else
  265. {
  266. $height = ceil((float) bcmul($sizes->height, $width_ratio, 10));
  267. $width = ceil((float) bcmul($sizes->width, $width_ratio, 10));
  268. }
  269. }
  270. else
  271. {
  272. $width_ratio = $width / $sizes->width;
  273. $height_ratio = $height / $sizes->height;
  274. if ($width_ratio >= $height_ratio)
  275. {
  276. $height = ceil($sizes->height * $height_ratio);
  277. $width = ceil($sizes->width * $height_ratio);
  278. }
  279. else
  280. {
  281. $height = ceil($sizes->height * $width_ratio);
  282. $width = ceil($sizes->width * $width_ratio);
  283. }
  284. }
  285. }
  286. if ($pad)
  287. {
  288. $x = floor(($origwidth - $width) / 2);
  289. $y = floor(($origheight - $height) / 2);
  290. }
  291. else
  292. {
  293. $origwidth = $width;
  294. $origheight = $height;
  295. }
  296. return array(
  297. 'width' => $width,
  298. 'height' => $height,
  299. 'cwidth' => $origwidth,
  300. 'cheight' => $origheight,
  301. 'x' => $x,
  302. 'y' => $y
  303. );
  304. }
  305. public function crop_resize($width, $height = null)
  306. {
  307. is_null($height) and $height = $width;
  308. $this->queue('crop_resize', $width, $height);
  309. return $this;
  310. }
  311. protected function _crop_resize($width, $height)
  312. {
  313. // Determine the crop size
  314. $sizes = $this->sizes();
  315. $width = $this->convert_number($width, true);
  316. $height = $this->convert_number($height, false);
  317. if (function_exists('bcdiv'))
  318. {
  319. if (bccomp(bcdiv($sizes->width, $width, 10), bcdiv($sizes->height, $height, 10), 10) < 1)
  320. {
  321. $this->_resize($width, 0, true, false);
  322. }
  323. else
  324. {
  325. $this->_resize(0, $height, true, false);
  326. }
  327. }
  328. else
  329. {
  330. if ($sizes->width / $width < $sizes->height / $height)
  331. {
  332. $this->_resize($width, 0, true, false);
  333. }
  334. else
  335. {
  336. $this->_resize(0, $height, true, false);
  337. }
  338. }
  339. $sizes = $this->sizes();
  340. $y = floor(max(0, $sizes->height - $height) / 2);
  341. $x = floor(max(0, $sizes->width - $width) / 2);
  342. $this->_crop($x, $y, $x + $width, $y + $height);
  343. }
  344. /**
  345. * Rotates the image
  346. *
  347. * @param integer $degrees The degrees to rotate, negatives integers allowed.
  348. * @return Image_Driver
  349. */
  350. public function rotate($degrees)
  351. {
  352. $this->queue('rotate', $degrees);
  353. return $this;
  354. }
  355. /**
  356. * Executes the rotate event when the queue is ran.
  357. *
  358. * Formats the rotate method input for use with driver specific methods
  359. *
  360. * @param integer $degrees The degrees to rotate, negatives integers allowed.
  361. * @return array An array of variables for the specific driver.
  362. */
  363. protected function _rotate($degrees)
  364. {
  365. $degrees %= 360;
  366. if ($degrees < 0)
  367. {
  368. $degrees = 360 + $degrees;
  369. }
  370. return array(
  371. 'degrees' => $degrees
  372. );
  373. }
  374. /**
  375. * Adds a watermark to the image.
  376. *
  377. * @param string $filename The filename of the watermark file to use.
  378. * @param string $position The position of the watermark, ex: "bottom right", "center center", "top left"
  379. * @param integer $padding The amount of padding (in pixels) from the position.
  380. * @return Image_Driver
  381. */
  382. public function watermark($filename, $position, $padding = 5)
  383. {
  384. $this->queue('watermark', $filename, $position, $padding);
  385. return $this;
  386. }
  387. /**
  388. * Executes the watermark event when the queue is ran.
  389. *
  390. * Formats the watermark method input for use with driver specific methods
  391. *
  392. * @param string $filename The filename of the watermark file to use.
  393. * @param string $position The position of the watermark, ex: "bottom right", "center center", "top left"
  394. * @param integer $padding The amount of padding (in pixels) from the position.
  395. * @return array An array of variables for the specific driver.
  396. */
  397. protected function _watermark($filename, $position, $padding = 5)
  398. {
  399. $filename = realpath($filename);
  400. $return = false;
  401. if (file_exists($filename) and $this->check_extension($filename, false))
  402. {
  403. $x = 0;
  404. $y = 0;
  405. $wsizes = $this->sizes($filename);
  406. $sizes = $this->sizes();
  407. // Get the x and y positions.
  408. list($ypos, $xpos) = explode(' ', $position);
  409. switch ($xpos)
  410. {
  411. case 'left':
  412. $x = $padding;
  413. break;
  414. case 'middle':
  415. case 'center':
  416. $x = ($sizes->width / 2) - ($wsizes->width / 2);
  417. break;
  418. case 'right':
  419. $x = $sizes->width - $wsizes->width - $padding;
  420. break;
  421. }
  422. switch ($ypos)
  423. {
  424. case 'top':
  425. $y = $padding;
  426. break;
  427. case 'middle':
  428. case 'center':
  429. $y = ($sizes->height / 2) - ($wsizes->height / 2);
  430. break;
  431. case 'bottom':
  432. $y = $sizes->height - $wsizes->height - $padding;
  433. break;
  434. }
  435. $this->debug("Watermark being placed at $x,$y");
  436. $return = array(
  437. 'filename' => $filename,
  438. 'x' => $x,
  439. 'y' => $y,
  440. 'padding' => $padding
  441. );
  442. }
  443. return $return;
  444. }
  445. /**
  446. * Adds a border to the image.
  447. *
  448. * @param integer $size The side of the border, in pixels.
  449. * @param string $color A hexadecimal color.
  450. * @return Image_Driver
  451. */
  452. public function border($size, $color = null)
  453. {
  454. $this->queue('border', $size, $color);
  455. return $this;
  456. }
  457. /**
  458. * Executes the border event when the queue is ran.
  459. *
  460. * Formats the border method input for use with driver specific methods
  461. *
  462. * @param integer $size The side of the border, in pixels.
  463. * @param string $color A hexadecimal color.
  464. * @return array An array of variables for the specific driver.
  465. */
  466. protected function _border($size, $color = null)
  467. {
  468. empty($color) and $color = $this->config['bgcolor'];
  469. return array(
  470. 'size' => $size,
  471. 'color' => $color
  472. );
  473. }
  474. /**
  475. * Masks the image using the alpha channel of the image input.
  476. *
  477. * @param string $maskimage The location of the image to use as the mask
  478. * @return Image_Driver
  479. */
  480. public function mask($maskimage)
  481. {
  482. $this->queue('mask', $maskimage);
  483. return $this;
  484. }
  485. /**
  486. * Executes the mask event when the queue is ran.
  487. *
  488. * Formats the mask method input for use with driver specific methods
  489. *
  490. * @param string $maskimage The location of the image to use as the mask
  491. * @return array An array of variables for the specific driver.
  492. */
  493. protected function _mask($maskimage)
  494. {
  495. return array(
  496. 'maskimage' => $maskimage
  497. );
  498. }
  499. /**
  500. * Adds rounded corners to the image.
  501. *
  502. * @param integer $radius
  503. * @param integer $sides Accepts any combination of "tl tr bl br" separated by spaces, or null for all sides
  504. * @param integer $antialias Sets the antialias range.
  505. * @return Image_Driver
  506. */
  507. public function rounded($radius, $sides = null, $antialias = null)
  508. {
  509. $this->queue('rounded', $radius, $sides, $antialias);
  510. return $this;
  511. }
  512. /**
  513. * Executes the rounded event when the queue is ran.
  514. *
  515. * Formats the rounded method input for use with driver specific methods
  516. *
  517. * @param integer $radius
  518. * @param integer $sides Accepts any combination of "tl tr bl br" separated by spaces, or null for all sides
  519. * @param integer $antialias Sets the antialias range.
  520. * @return array An array of variables for the specific driver.
  521. */
  522. protected function _rounded($radius, $sides, $antialias)
  523. {
  524. $radius < 0 and $radius = 0;
  525. $tl = $tr = $bl = $br = $sides == null;
  526. if ($sides != null)
  527. {
  528. $sides = explode(' ', $sides);
  529. foreach ($sides as $side)
  530. {
  531. if ($side == 'tl' or $side == 'tr' or $side == 'bl' or $side == 'br')
  532. {
  533. $$side = true;
  534. }
  535. }
  536. }
  537. $antialias == null and $antialias = 1;
  538. return array(
  539. 'radius' => $radius,
  540. 'tl' => $tl,
  541. 'tr' => $tr,
  542. 'bl' => $bl,
  543. 'br' => $br,
  544. 'antialias' => $antialias
  545. );
  546. }
  547. /**
  548. * Turns the image into a grayscale version
  549. *
  550. * @return Image_Driver
  551. */
  552. public function grayscale()
  553. {
  554. $this->queue('grayscale');
  555. return $this;
  556. }
  557. /**
  558. * Executes the grayscale event when the queue is ran.
  559. */
  560. abstract protected function _grayscale();
  561. /**
  562. * Saves the image, and optionally attempts to set permissions
  563. *
  564. * @param string $filename The location where to save the image.
  565. * @param string $permissions Allows unix style permissions
  566. * @return array
  567. */
  568. public function save($filename, $permissions = null)
  569. {
  570. $directory = dirname($filename);
  571. if ( ! is_dir($directory))
  572. {
  573. throw new \OutOfBoundsException("Could not find directory \"$directory\"");
  574. }
  575. if ( ! $this->check_extension($filename, true))
  576. {
  577. $filename .= "." . $this->image_extension;
  578. }
  579. // Touch the file
  580. if ( ! touch($filename))
  581. {
  582. throw new \RuntimeException("Do not have permission to write to \"$filename\"");
  583. }
  584. // Set the new permissions
  585. if ($permissions != null and ! chmod($filename, $permissions))
  586. {
  587. throw new \RuntimeException("Could not set permissions on the file.");
  588. }
  589. $this->debug("", "Saving image as <code>$filename</code>");
  590. return array(
  591. 'filename' => $filename
  592. );
  593. }
  594. /**
  595. * Saves the file in the original location, adding the append and prepend to the filename.
  596. *
  597. * @param string $append The string to append to the filename
  598. * @param string $prepend The string to prepend to the filename
  599. * @param string $extension The extension to save the image as, null defaults to the loaded images extension.
  600. * @param integer $permissions The permissions to attempt to set on the file.
  601. * @return Image_Driver
  602. */
  603. public function save_pa($append, $prepend = null, $extension = null, $permissions = null)
  604. {
  605. $filename = substr($this->image_filename, 0, -(strlen($this->image_extension) + 1));
  606. $fullpath = $this->image_directory.'/'.$append.$filename.$prepend.'.'.
  607. ($extension !== null ? $extension : $this->image_extension);
  608. $this->save($fullpath, $permissions);
  609. return $this;
  610. }
  611. /**
  612. * Outputs the file directly to the user.
  613. *
  614. * @param string $filetype The extension type to use. Ex: png, jpg, gif
  615. * @return array
  616. */
  617. public function output($filetype = null)
  618. {
  619. if ($filetype == null)
  620. {
  621. $filetype = $this->config['filetype'] == null ? $this->image_extension : $this->config['filetype'];
  622. }
  623. if ($this->check_extension($filetype, false))
  624. {
  625. if ( ! $this->config['debug'])
  626. {
  627. $mimetype = $filetype === 'jpg' ? 'jpeg' : $filetype;
  628. header('Content-Type: image/' . $mimetype);
  629. }
  630. $this->new_extension = $filetype;
  631. }
  632. else
  633. {
  634. throw new \FuelException("Image extension $filetype is unsupported.");
  635. }
  636. $this->debug('', "Outputting image as $filetype");
  637. return array(
  638. 'filetype' => $filetype
  639. );
  640. }
  641. /**
  642. * Returns sizes for the currently loaded image, or the image given in the $filename.
  643. *
  644. * @param string $filename The location of the file to get sizes for.
  645. * @return object An object containing width and height variables.
  646. */
  647. abstract public function sizes($filename = null);
  648. /**
  649. * Adds a background to the image using the 'bgcolor' config option.
  650. */
  651. abstract protected function add_background();
  652. /**
  653. * Creates a new color usable by all drivers.
  654. *
  655. * @param string $hex The hex code of the color
  656. * @return array rgba representation of the hex and alpha values.
  657. */
  658. protected function create_hex_color($hex)
  659. {
  660. if ($hex == null)
  661. {
  662. $red = 0;
  663. $green = 0;
  664. $blue = 0;
  665. }
  666. else
  667. {
  668. // Check if theres a # in front
  669. if (substr($hex, 0, 1) == '#')
  670. {
  671. $hex = substr($hex, 1);
  672. }
  673. // Break apart the hex
  674. if (strlen($hex) == 6)
  675. {
  676. $red = hexdec(substr($hex, 0, 2));
  677. $green = hexdec(substr($hex, 2, 2));
  678. $blue = hexdec(substr($hex, 4, 2));
  679. }
  680. else
  681. {
  682. $red = hexdec(substr($hex, 0, 1).substr($hex, 0, 1));
  683. $green = hexdec(substr($hex, 1, 1).substr($hex, 1, 1));
  684. $blue = hexdec(substr($hex, 2, 1).substr($hex, 2, 1));
  685. }
  686. }
  687. return array(
  688. 'red' => $red,
  689. 'green' => $green,
  690. 'blue' => $blue,
  691. );
  692. }
  693. /**
  694. * Checks if the extension is accepted by this library, and if its valid sets the $this->image_extension variable.
  695. *
  696. * @param string $filename
  697. * @param boolean $writevar Decides if the extension should be written to $this->image_extension
  698. * @param mixed $force_extension Decides if the extension should be overridden with this (or false)
  699. * @return boolean
  700. */
  701. protected function check_extension($filename, $writevar = true, $force_extension = false)
  702. {
  703. $return = false;
  704. if ($force_extension !== false and in_array($force_extension, $this->accepted_extensions))
  705. {
  706. return $force_extension;
  707. }
  708. foreach ($this->accepted_extensions as $ext)
  709. {
  710. if (strtolower(substr($filename, strlen($ext) * -1)) == strtolower($ext))
  711. {
  712. $writevar and $this->image_extension = $ext;
  713. $return = $ext;
  714. }
  715. }
  716. return $return;
  717. }
  718. /**
  719. * Converts percentages, negatives, and other values to absolute integers.
  720. *
  721. * @param string $input
  722. * @param boolean $x Determines if the number relates to the x-axis or y-axis.
  723. * @return integer The converted number, usable with the image being edited.
  724. */
  725. protected function convert_number($input, $x = null)
  726. {
  727. // Sanitize double negatives
  728. $input = str_replace('--', '', $input);
  729. $orig = $input;
  730. $sizes = $this->sizes();
  731. $size = $x ? $sizes->width : $sizes->height;
  732. // Convert percentages to absolutes
  733. if (substr($input, -1) == '%')
  734. {
  735. $input = floor((substr($input, 0, -1) / 100) * $size);
  736. }
  737. // Negatives are based off the bottom right
  738. if ($x !== null and $input < 0)
  739. {
  740. $input = $size + $input;
  741. }
  742. return $input;
  743. }
  744. /**
  745. * Queues a function to run at a later time.
  746. *
  747. * @param string $function The name of the function to be ran, without the leading _
  748. */
  749. protected function queue($function)
  750. {
  751. $func = func_get_args();
  752. $tmpfunc = array();
  753. for ($i = 0; $i < count($func); $i++)
  754. {
  755. $tmpfunc[$i] = var_export($func[$i], true);
  756. }
  757. $this->debug("Queued <code>" . implode(", ", $tmpfunc) . "</code>");
  758. $this->queued_actions[] = $func;
  759. }
  760. /**
  761. * Runs all queued actions on the loaded image.
  762. *
  763. * @param boolean $clear Decides if the queue should be cleared once completed.
  764. */
  765. public function run_queue($clear = null)
  766. {
  767. foreach ($this->queued_actions as $action)
  768. {
  769. $tmpfunc = array();
  770. for ($i = 0; $i < count($action); $i++)
  771. {
  772. $tmpfunc[$i] = var_export($action[$i], true);
  773. }
  774. $this->debug('', "<b>Executing <code>" . implode(", ", $tmpfunc) . "</code></b>");
  775. call_user_func_array(array(&$this, '_' . $action[0]), array_slice($action, 1));
  776. }
  777. if (($clear === null and $this->config['clear_queue']) or $clear === true)
  778. {
  779. $this->queued_actions = array();
  780. }
  781. }
  782. /**
  783. * Reloads the image.
  784. *
  785. * @return Image_Driver
  786. */
  787. public function reload()
  788. {
  789. $this->debug("Reloading was called!");
  790. $this->load($this->image_fullpath, false, $this->image_extension);
  791. return $this;
  792. }
  793. /**
  794. * Used for debugging image output.
  795. *
  796. * @param string $message
  797. */
  798. protected function debug()
  799. {
  800. if ($this->config['debug'])
  801. {
  802. $messages = func_get_args();
  803. foreach ($messages as $message)
  804. {
  805. echo '<div>' . $message . '&nbsp;</div>';
  806. }
  807. }
  808. }
  809. }