PageRenderTime 24ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/classes/image/driver.php

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