sfThumbnail.class.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. <?php
  2. /*
  3. * This file is part of the symfony package.
  4. * (c) 2004-2007 Fabien Potencier <fabien.potencier@symfony-project.com>
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. /**
  10. * sfThumbnail provides a mechanism for creating thumbnail images.
  11. *
  12. * This is taken from Harry Fueck's Thumbnail class and
  13. * converted for PHP5 strict compliance for use with symfony.
  14. *
  15. * @package sfThumbnailPlugin
  16. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  17. * @author Benjamin Meynell <bmeynell@colorado.edu>
  18. */
  19. class sfThumbnail
  20. {
  21. /**
  22. * Width of thumbnail in pixels
  23. */
  24. protected $thumbWidth;
  25. /**
  26. * Height of thumbnail in pixels
  27. */
  28. protected $thumbHeight;
  29. /**
  30. * Temporary file if the source is not local
  31. */
  32. protected $tempFile = null;
  33. /**
  34. * Thumbnail constructor
  35. *
  36. * @param int (optional) max width of thumbnail
  37. * @param int (optional) max height of thumbnail
  38. * @param boolean (optional) if true image scales
  39. * @param boolean (optional) if true inflate small images
  40. * @param string (optional) adapter class name
  41. * @param array (optional) adapter options
  42. */
  43. public function __construct($maxWidth = null, $maxHeight = null, $scale = true, $inflate = true, $quality = 75, $adapterClass = null, $adapterOptions = array())
  44. {
  45. if (!$adapterClass)
  46. {
  47. if (extension_loaded('gd'))
  48. {
  49. $adapterClass = 'sfGDAdapter';
  50. }
  51. else
  52. {
  53. $adapterClass = 'sfImageMagickAdapter';
  54. }
  55. }
  56. $this->adapter = new $adapterClass($maxWidth, $maxHeight, $scale, $inflate, $quality, $adapterOptions);
  57. }
  58. /**
  59. * Loads an image from a file or URL and creates an internal thumbnail out of it
  60. *
  61. * @param string filename (with absolute path) of the image to load. If the filename is a http(s) URL, then an attempt to download the file will be made.
  62. *
  63. * @return boolean True if the image was properly loaded
  64. * @throws Exception If the image cannot be loaded, or if its mime type is not supported
  65. */
  66. public function loadFile($image)
  67. {
  68. //if (eregi('http(s)?://', $image))
  69. if (preg_match('http(s)?://', $image))
  70. {
  71. if (class_exists('sfWebBrowser'))
  72. {
  73. if (!is_null($this->tempFile)) {
  74. unlink($this->tempFile);
  75. }
  76. $this->tempFile = tempnam('/tmp', 'sfThumbnailPlugin');
  77. $b = new sfWebBrowser();
  78. try
  79. {
  80. $b->get($image);
  81. if ($b->getResponseCode() != 200) {
  82. throw new Exception(sprintf('%s returned error code %s', $image, $b->getResponseCode()));
  83. }
  84. file_put_contents($this->tempFile, $b->getResponseText());
  85. if (!filesize($this->tempFile)) {
  86. throw new Exception('downloaded file is empty');
  87. } else {
  88. $image = $this->tempFile;
  89. }
  90. }
  91. catch (Exception $e)
  92. {
  93. throw new Exception("Source image is a URL but it cannot be used because ". $e->getMessage());
  94. }
  95. }
  96. else
  97. {
  98. throw new Exception("Source image is a URL but sfWebBrowserPlugin is not installed");
  99. }
  100. }
  101. else
  102. {
  103. if (!is_readable($image))
  104. {
  105. throw new Exception(sprintf('The file "%s" is not readable.', $image));
  106. }
  107. }
  108. $this->adapter->loadFile($this, $image);
  109. }
  110. /**
  111. * Loads an image from a string (e.g. database) and creates an internal thumbnail out of it
  112. *
  113. * @param string the image string (must be a format accepted by imagecreatefromstring())
  114. * @param string mime type of the image
  115. *
  116. * @return boolean True if the image was properly loaded
  117. * @access public
  118. * @throws Exception If image mime type is not supported
  119. */
  120. public function loadData($image, $mime)
  121. {
  122. $this->adapter->loadData($this, $image, $mime);
  123. }
  124. /**
  125. * Saves the thumbnail to the filesystem
  126. * If no target mime type is specified, the thumbnail is created with the same mime type as the source file.
  127. *
  128. * @param string the image thumbnail file destination (with absolute path)
  129. * @param string The mime-type of the thumbnail (possible values are 'image/jpeg', 'image/png', and 'image/gif')
  130. *
  131. * @access public
  132. * @return void
  133. */
  134. public function save($thumbDest, $targetMime = null)
  135. {
  136. $this->adapter->save($this, $thumbDest, $targetMime);
  137. }
  138. /**
  139. * Returns the thumbnail as a string
  140. * If no target mime type is specified, the thumbnail is created with the same mime type as the source file.
  141. *
  142. *
  143. * @param string The mime-type of the thumbnail (possible values are adapter dependent)
  144. *
  145. * @access public
  146. * @return string
  147. */
  148. public function toString($targetMime = null)
  149. {
  150. return $this->adapter->toString($this, $targetMime);
  151. }
  152. public function toResource()
  153. {
  154. return $this->adapter->toResource($this);
  155. }
  156. public function freeSource()
  157. {
  158. if (!is_null($this->tempFile)) {
  159. unlink($this->tempFile);
  160. }
  161. $this->adapter->freeSource();
  162. }
  163. public function freeThumb()
  164. {
  165. $this->adapter->freeThumb();
  166. }
  167. public function freeAll()
  168. {
  169. $this->adapter->freeSource();
  170. $this->adapter->freeThumb();
  171. }
  172. /**
  173. * Returns the width of the thumbnail
  174. */
  175. public function getThumbWidth()
  176. {
  177. return $this->thumbWidth;
  178. }
  179. /**
  180. * Returns the height of the thumbnail
  181. */
  182. public function getThumbHeight()
  183. {
  184. return $this->thumbHeight;
  185. }
  186. /**
  187. * Returns the mime type of the source image
  188. */
  189. public function getMime()
  190. {
  191. return $this->adapter->getSourceMime();
  192. }
  193. /**
  194. * Computes the thumbnail width and height
  195. * Used by adapter
  196. */
  197. public function initThumb($sourceWidth, $sourceHeight, $maxWidth, $maxHeight, $scale, $inflate)
  198. {
  199. if ($maxWidth > 0)
  200. {
  201. $ratioWidth = $maxWidth / $sourceWidth;
  202. }
  203. if ($maxHeight > 0)
  204. {
  205. $ratioHeight = $maxHeight / $sourceHeight;
  206. }
  207. if ($scale)
  208. {
  209. if ($maxWidth && $maxHeight)
  210. {
  211. $ratio = ($ratioWidth < $ratioHeight) ? $ratioWidth : $ratioHeight;
  212. }
  213. if ($maxWidth xor $maxHeight)
  214. {
  215. $ratio = (isset($ratioWidth)) ? $ratioWidth : $ratioHeight;
  216. }
  217. if ((!$maxWidth && !$maxHeight) || (!$inflate && $ratio > 1))
  218. {
  219. $ratio = 1;
  220. }
  221. $this->thumbWidth = floor($ratio * $sourceWidth);
  222. $this->thumbHeight = ceil($ratio * $sourceHeight);
  223. }
  224. else
  225. {
  226. if (!isset($ratioWidth) || (!$inflate && $ratioWidth > 1))
  227. {
  228. $ratioWidth = 1;
  229. }
  230. if (!isset($ratioHeight) || (!$inflate && $ratioHeight > 1))
  231. {
  232. $ratioHeight = 1;
  233. }
  234. $this->thumbWidth = floor($ratioWidth * $sourceWidth);
  235. $this->thumbHeight = ceil($ratioHeight * $sourceHeight);
  236. }
  237. }
  238. public function __destruct()
  239. {
  240. $this->freeAll();
  241. }
  242. }