Graphics.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | PEAR :: Cache |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 1997-2003 The PHP Group |
  6. // +----------------------------------------------------------------------+
  7. // | This source file is subject to version 2.0 of the PHP license, |
  8. // | that is bundled with this package in the file LICENSE, and is |
  9. // | available at through the world-wide-web at |
  10. // | http://www.php.net/license/2_02.txt. |
  11. // | If you did not receive a copy of the PHP license and are unable to |
  12. // | obtain it through the world-wide-web, please send a note to |
  13. // | license@php.net so we can mail you a copy immediately. |
  14. // +----------------------------------------------------------------------+
  15. // | Authors: Ulf Wendel <ulf.wendel@phpdoc.de> |
  16. // +----------------------------------------------------------------------+
  17. //
  18. // $Id: Graphics.php,v 1.5 2003/01/04 11:54:45 mj Exp $
  19. require_once 'Cache.php';
  20. /**
  21. * Graphics disk cache.
  22. *
  23. * The usual way to create images is to pass some arguments that describe the image
  24. * to a script that dynamically creates an image. For every image of a page
  25. * a new PHP interpreter gets started. This is a good way to kill your webserver.
  26. *
  27. * When dealing with dynamically generated images you should not call another script
  28. * to generate the images but generate the images by the script that produces the page
  29. * that contains the images. This is a major improvement but it's only half the way.
  30. *
  31. * There's no need to rerender an image on every request. A simple disk cache can reduce
  32. * the computation time dramatically. This is what the class graphics_cache is for.
  33. *
  34. * Usage:
  35. *
  36. * // create an instance of the graphics cache
  37. * $cache = new graphics_cache;
  38. *
  39. * $img = ImageCreate(...);
  40. *
  41. * // compute an ID for your image based on typical parameters
  42. * $id = m5d( $size, $colors, $label);
  43. *
  44. * // check if it's cached
  45. * if (!($link = $cache->getImageLink($id, 'gif'))) {
  46. *
  47. * // hmmm, it's not cached, create it
  48. * ...
  49. * // cacheImageLink() and cacheImage() make the ImageGIF() call!
  50. * // cacheImage() returns the value of ImageGIF() [etc.], cacheImageLink() returns a URL
  51. * $link = $cache->cacheImageLink($id, $img, 'gif');
  52. *
  53. * }
  54. *
  55. * // Ok, let's build the ImageLink
  56. * $size = getImageSize($link[0]);
  57. * printf('<img src="%s" %s>', $link[1], $size[3]);
  58. *
  59. * // for cacheImage():
  60. * // header('Content-type: image/gif'); print $cache->cacheImage($id, $img, 'gif');
  61. *
  62. *
  63. * The class requires PHP 4.0.2+ [ImageType()]. Note that cacheImage() works with
  64. * the output buffer. Modify it if required!
  65. *
  66. * @author Ulf Wendel <ulf.wendel@phpdoc.de>
  67. * @version $Id: Graphics.php,v 1.5 2003/01/04 11:54:45 mj Exp $
  68. * @package Cache
  69. */
  70. class Cache_Graphics extends Cache {
  71. /**
  72. * Cache URL prefix.
  73. *
  74. * Make sure that the cache URL prefix points to the $cache_dir, otherwise
  75. * your links will be broken. Use setCacheURL to specify the cache_url and
  76. * setCacheDir() for the cache_dir.
  77. *
  78. * @var string
  79. * @see setCacheURL(), setCacheDir()
  80. */
  81. var $cache_url = '';
  82. /**
  83. * Directory where cached files get stored.
  84. * s
  85. * Make sure that the cache_dir is writable and offers enough space. Check
  86. * also if your cache_url points to the directory. Use setCacheDir() to set
  87. * the variable.
  88. *
  89. * @var string
  90. * @see setCacheDir(), setCacheURL()
  91. */
  92. var $cache_dir = '';
  93. /**
  94. * Nameprefix of cached files.
  95. *
  96. * Per default the prefix "graphics_" gets used. You might use this
  97. * for versioning or to ease (manual) clean ups.
  98. *
  99. * @var string
  100. */
  101. var $cache_file_prefix = 'graphics_';
  102. /**
  103. * Cache container group.
  104. *
  105. * @var string
  106. */
  107. var $cache_group = 'graphics';
  108. /**
  109. * Mapping from supported image type to a ImageType() constant.
  110. *
  111. * Referr to the PHP manual for more informations on ImageType()
  112. *
  113. * @var array
  114. * @link http://www.php.net/ImageType
  115. */
  116. var $imagetypes = array(
  117. 'gif' => IMG_GIF,
  118. 'jpg' => IMG_JPG,
  119. 'png' => IMG_PNG,
  120. 'wbmp' => IMG_WBMP
  121. );
  122. /**
  123. * Instantiates a cache file container.
  124. *
  125. */
  126. function Cache_Graphics() {
  127. $this->Cache('file', array('cache_dir' => $this->cache_dir, 'filename_prefix' => $this->cache_file_prefix));
  128. } // end constructor
  129. /**
  130. * Returns the content of a cached image file.
  131. *
  132. * This function can be used to send the image directly to the browser.
  133. * Make sure that you send a correspondending header before sending the image itself.
  134. *
  135. * Always try to get the image from the cache before you compute it. See
  136. * the class docs for an example.
  137. *
  138. * @param string Image-ID
  139. * @param string Image type: gif, jpg, png, wbmp
  140. * @return string Image file contents if a cached file exists otherwise an empty string
  141. * @see cacheImage()
  142. */
  143. function getImage($id, $format = 'png') {
  144. $id = $this->generateID($id, $format);
  145. return $this->get($id, $this->cache_group);
  146. } // end func getImage
  147. /**
  148. * Returns an array with a link to the cached image and the image file path.
  149. *
  150. * Always try to get the image from the cache before you compute it. See
  151. * the class docs for an example.
  152. *
  153. * @param string Image-ID
  154. * @param string Image type: gif, jpg, png, wbmp
  155. * @return array [ full path to the image file, image url ]
  156. * @throw Cache_Error
  157. * @see cacheImageLink()
  158. */
  159. function getImageLink($id, $format = 'png') {
  160. $id = $this->generateID($id, $format);
  161. if (!$this->container->idExists($id, $this->cache_group))
  162. return array();
  163. $file = $this->cache_url . $this->cache_file_prefix . $id;
  164. return array($this->container->getFilename($id, $this->cache_group), $file);
  165. } // end func getImageLink
  166. /**
  167. * Create an image from the given image handler, cache it and return the file content.
  168. *
  169. * Always try to retrive the image from the cache before you compute it.
  170. *
  171. * Warning: this function uses the output buffer. If you expect collisions
  172. * modify the code.
  173. *
  174. * @param string Image-ID. Used as a part of the cache filename.
  175. * Use md5() to generate a "unique" ID for your image
  176. * based on characteristic values such as the color, size etc.
  177. * @param string Image handler to create the image from.
  178. * @param string Image type: gif, jpg, png, wbmp. Also used as filename suffix.
  179. * If an unsupported type is requested the functions tries to
  180. * fallback to a supported type before throwing an exeption.
  181. * @return string Image content returned by ImageGIF/...
  182. * @throws Cache_Error
  183. * @access public
  184. * @see getImage()
  185. */
  186. function cacheImage($id, $img, $format = 'png') {
  187. if (!$id)
  188. return new Cache_Error('You must provide an ID for and image to be cached!', __FILE__, __LINE__);
  189. $id = $this->generateID($id, $format);
  190. $types = ImageTypes();
  191. // Check if the requested image type is supported by the GD lib.
  192. // If not, try a callback to the first available image type.
  193. if (!isset($this->imagetypes[$format]) || !($types & $this->imagetypes[$format])) {
  194. foreach ($this->imagetypes as $supported => $bitmask) {
  195. if ($types & $bitmask) {
  196. new Cache_Error("The build in GD lib does not support the image type $format. Fallback to $supported.", __FILE__, __LINE__);
  197. } else {
  198. return new Cache_Error("Hmm, is your PHP build with GD support? Can't find any supported types.", __FILE__, __LINE__);
  199. }
  200. }
  201. }
  202. if ($image = $this->get($id, $this->cache_group))
  203. return $image;
  204. // save the image to the output buffer, write it to disk and
  205. // return the image.
  206. ob_end_clean();
  207. ob_start();
  208. if (strtoupper($format) == "JPG") {
  209. $genFormat = "JPEG";
  210. } else {
  211. $genFormat = strtoupper($format);
  212. }
  213. // generate the image
  214. $func = 'Image' . $genFormat;
  215. $func($img);
  216. ImageDestroy($img);
  217. ob_end();
  218. $image = ob_get_contents();
  219. ob_end_clean();
  220. // save the generated image to disk
  221. $this->save($id, $image, 0, $this->cache_group);
  222. return $image;
  223. } // end func cacheImage
  224. /**
  225. * Create an image from the given image handler, cache it and return a url and the file path of the image.
  226. *
  227. * Always try to retrive the image from the cache before you compute it.
  228. *
  229. * @param string Image-ID. Used as a part of the cache filename.
  230. * Use md5() to generate a "unique" ID for your image
  231. * based on characteristic values such as the color, size etc.
  232. * @param string Image handler to create the image from.
  233. * @param string Image type: gif, jpg, png, wbmp. Also used as filename suffix.
  234. * If an unsupported type is requested the functions tries to
  235. * fallback to a supported type before throwing an exeption.
  236. * @return array [ full path to the image file, image url ]
  237. * @throws Cache_Error
  238. * @access public
  239. */
  240. function cacheImageLink($id, &$img, $format = 'png') {
  241. if (!$id)
  242. return new Cache_Error ('You must provide an ID for and image to be cached!', __FILE__, __LINE__);
  243. $id = $this->generateID($id, $format);
  244. $types = ImageTypes();
  245. // Check if the requested image type is supported by the GD lib.
  246. // If not, try a callback to the first available image type.
  247. if (!isset($this->imagetypes[$format]) || !($types & $this->imagetypes[$format])) {
  248. foreach ($this->imagetypes as $supported => $bitmask)
  249. if ($types & $bitmask)
  250. new Cache_Error("The build in GD lib does not support the image type $format. Fallback to $supported.", __FILE__, __LINE__);
  251. else
  252. return new Cache_Error("Hmm, is your PHP build with GD support? Can't find any supported types.", __FILE__, __LINE__);
  253. }
  254. $url = $this->cache_url . $this->cache_file_prefix . $id;
  255. $ffile = $this->container->getFilename($id, $this->cache_group);
  256. if ($this->isCached($id, $this->cache_group) && !isExpired($id, $this->cache_group))
  257. return array($ffile, $url);
  258. if (strtoupper($format) == "JPG") {
  259. $genFormat = "JPEG";
  260. } else {
  261. $genFormat = strtoupper($format);
  262. }
  263. $func = 'Image' . $genFormat;
  264. $func($img, $ffile);
  265. ImageDestroy($img);
  266. return array($ffile, $url);
  267. } // end func cacheImageLink
  268. /**
  269. * Sets the URL prefix used when rendering HTML Tags.
  270. *
  271. * Make sure that the URL matches the cache directory,
  272. * otherwise you'll get broken links.
  273. *
  274. * @param string
  275. * @access public
  276. * @see setCacheDir()
  277. */
  278. function setCacheURL($cache_url) {
  279. if ($cache_url && '/' != substr($cache_url, 1))
  280. $cache_url .= '/';
  281. $this->cache_url = $cache_url;
  282. } // end func setCacheURL
  283. /**
  284. * Sets the directory where to cache generated Images
  285. *
  286. * @param string
  287. * @access public
  288. * @see setCacheURL()
  289. */
  290. function setCacheDir($cache_dir) {
  291. if ($cache_dir && '/' != substr($cache_dir, 1))
  292. $cache_dir .= '/';
  293. $this->cache_dir = $cache_dir;
  294. $this->container->cache_dir = $cache_dir;
  295. } // end func setCacheDir
  296. function generateID($variable, $format = 'png') {
  297. return md5(serialize($variable)) . '.' . $format;
  298. } // end func generateID
  299. } // end class Cache_Graphics
  300. ?>