Lithron.LImage
[ class tree: Lithron.LImage ] [ index: Lithron.LImage ] [ all elements ]

Source for file LImage.php

Documentation is available at LImage.php

  1. <?php
  2.  
  3.  
  4. /**
  5. * Class file.
  6. *
  7. * @license http://opensource.org/licenses/mozilla1.1.php Mozilla Public License
  8. * @copyright 2005, diemeisterei GmbH. All rights reserved.
  9. * @author $Author: schmunk $
  10. * @version $Revision: 269 $ $Date: 2006-06-12 08:29:29 +0200 (Mo, 12 Jun 2006) $
  11. * @package Lithron.LImage
  12. * @subpackage WebControls
  13. */
  14.  
  15. /**
  16. * This is a combination of an extended TImage and a wrapper for ImageMagick functions
  17. *
  18. * @package System.Web.UI.WebControls
  19. */
  20. class LImage extends TImage
  21. {
  22. private $SrcUrl;
  23. private $SrcRealpath;
  24. private $DestUrl;
  25. private $DestRealpath;
  26. private $OutputDir;
  27. private $SrcExt;
  28.  
  29. private $BinPath;
  30. private $Info;
  31.  
  32. public function setResize($value)
  33. {
  34. $this->setViewState('Resize', TPropertyValue :: ensureBoolean($value), '');
  35. }
  36. public function getResize()
  37. {
  38. return $this->getViewState('Resize', true);
  39. }
  40.  
  41. public function setDestWidth($value)
  42. {
  43. $this->setViewState('DestWidth', TPropertyValue :: ensureInteger($value), '');
  44. }
  45. public function getDestWidth()
  46. {
  47. return $this->getViewState('DestWidth');
  48. }
  49.  
  50. public function setDestHeight($value)
  51. {
  52. $this->setViewState('DestHeight', TPropertyValue :: ensureInteger($value), '');
  53. }
  54. public function getDestHeight()
  55. {
  56. return $this->getViewState('DestHeight');
  57. }
  58.  
  59. public function setDestQuality($value)
  60. {
  61. $this->setViewState('DestQuality', TPropertyValue :: ensureInteger($value), '');
  62. }
  63. public function getDestQuality()
  64. {
  65. return $this->getViewState('DestQuality', "50");
  66. }
  67.  
  68. public function setDestType($value)
  69. {
  70. $this->setViewState('DestType', TPropertyValue :: ensureString(strtoupper($value)), '');
  71. }
  72. public function getDestType()
  73. {
  74. return $this->getViewState('DestType');
  75. }
  76.  
  77. public function setDestColorSpace($value)
  78. {
  79. $this->setViewState('DestColorSpace', TPropertyValue :: ensureString($value), '');
  80. }
  81. public function getDestColorSpace()
  82. {
  83. return $this->getViewState('DestColorSpace', "rgb");
  84. }
  85.  
  86. public function setShowMimeTypeImage($value)
  87. {
  88. $this->setViewState('ShowMimeTypeImage', TPropertyValue :: ensureBoolean($value), '');
  89. }
  90. public function getShowMimeTypeImage()
  91. {
  92. return $this->getViewState('ShowMimeTypeImage', false);
  93. }
  94. public function setDestBackgroundColor($value)
  95. {
  96. $this->setViewState('BackgroundColor', TPropertyValue :: ensureString($value), '');
  97. }
  98. public function getDestBackgroundColor()
  99. {
  100. return $this->getViewState('BackgroundColor', null);
  101. }
  102.  
  103.  
  104. /**
  105. * @ignore
  106. */
  107. public function onInit($param)
  108. {
  109. #Prado :: trace("LImage onInit starting ... ", "Lithron.LImage");
  110. $param= $this->Application->getParameters();
  111. $this->OutputDir= $param->itemAt("OutputDir");
  112. parent :: onInit($param);
  113. #Prado :: trace("LImage onInit complete", "Lithron.LImage");
  114. }
  115.  
  116. function __construct()
  117. {
  118. $this->findImageMagick();
  119. if (empty($this->BinPath)){
  120. Prado::log("ImageMagick not found",8,"Lithron.LImage");
  121. return;
  122. }
  123. }
  124.  
  125. /**
  126. * @ignore
  127. */
  128. public function onPreRender($param)
  129. {
  130. if (empty($this->BinPath)){
  131. return;
  132. }
  133. if ($this->getResize() == true)
  134. {
  135. $this->generateImage();
  136. }
  137. parent :: onPreRender($param);
  138. }
  139.  
  140. public function doIdentify($file)
  141. {
  142. return $this->identify($file);
  143. }
  144.  
  145. /**
  146. * Searches ImageMagick in file system
  147. */
  148. private function findImageMagick()
  149. {
  150. if ($this->BinPath= $this->Application->getGlobalState("LImage:BinPath"))
  151. {
  152. putenv("PATH=" . $this->BinPath);
  153. return;
  154. }
  155.  
  156. $param= $this->Application->getParameters();
  157. $paths= explode(";", $param->itemAt("ImagickSearchPaths"));
  158. foreach ($paths AS $path)
  159. {
  160. if (!is_dir($path)) continue;
  161. #echo $path;exit;
  162. exec($path . "/identify -version", $output);
  163. if (isset ($output[0]) && strstr($output[0], "ImageMagick"))
  164. {
  165. $this->BinPath= $path . "/";
  166. $this->Application->setGlobalState("LImage:BinPath", $this->BinPath);
  167. return;
  168. #break;
  169. }
  170. #$this->BinPath;
  171. }
  172.  
  173. }
  174.  
  175. /**
  176. * Invokes image generation
  177. */
  178. private function generateImage()
  179. {
  180. #Prado :: trace("Generating image ... ", "Lithron.LImage");
  181.  
  182. $this->SrcUrl= $this->getImageUrl();
  183. $this->SrcRealpath= realpath($this->getImageUrl());
  184. $this->SrcExt= substr(strrchr($this->SrcUrl, "."), 1);
  185.  
  186. // check if missing
  187. if (!is_file($this->SrcUrl))
  188. {
  189. Prado :: log("File '" . $this->SrcUrl . "' missing", 3, "Lithron.LImage");
  190. $this->setImageUrl($this->publishAsset("mimetypes/missing.png"));
  191. return;
  192. }
  193.  
  194. // output folder
  195. $outputDir= realpath($this->OutputDir);
  196.  
  197. // check cache
  198. $file= $this->generateHash(); #.".".$outputType;
  199. if (is_file($outputDir . "/" . $file))
  200. {
  201. #Prado :: trace("Using cached file: {$file} <= '{$this->SrcUrl}' ", "Lithron.LImage");
  202. $this->setImageUrl($this->OutputDir . "/" . $file);
  203. return;
  204. }
  205.  
  206. // get file info
  207. $this->Info= $this->identify($this->SrcRealpath);
  208.  
  209. if (is_writable($outputDir))
  210. {
  211. $outputRealpath= $outputDir . "/" . $file;
  212. $clientUrl= $this->OutputDir . "/" . $file;
  213. // generate image
  214. if ($this->getShowMimeTypeImage() === true)
  215. {
  216. $this->generateAlternativeImage($this->SrcRealpath, $outputRealpath);
  217. }
  218. else
  219. {
  220. $this->convert($this->SrcRealpath, $outputRealpath);
  221. if (!is_file($outputRealpath))
  222. {
  223. $this->generateAlternativeImage($this->SrcRealpath, $outputRealpath);
  224. }
  225. }
  226.  
  227. $this->setImageUrl($clientUrl);
  228. }
  229. else
  230. {
  231. Prado :: log("OutputDir '" . $outputDir . "' is not writable", 3, "Lithron.LImage");
  232. }
  233.  
  234. }
  235. /**
  236. * Creates a unique fingerprint of the destination file
  237. */
  238. private function generateHash()
  239. {
  240. if ($cache= $this->Application->Cache)
  241. {
  242. $idString= $cache->get("LImage:" . $this->SrcUrl);
  243. }
  244. if (empty ($idString))
  245. {
  246. $idString= md5_file($this->SrcUrl);
  247. Prado :: trace("Creating new md5 for {$this->SrcUrl}", "Lithron.LImage");
  248. if ($cache)
  249. {
  250. $cache->set("LImage:" . $this->SrcUrl, $idString, 360);
  251. }
  252. }
  253. $_props= array (
  254. "DestWidth",
  255. "DestHeight",
  256. "DestType",
  257. "DestQuality",
  258. "DestColorSpace",
  259. "DestBackgroundColor",
  260. "ShowMimeTypeImage"
  261. );
  262.  
  263. foreach ($_props AS $prop)
  264. {
  265. $_eval= "return(\$this->get" . $prop . "());";
  266. $value= eval ($_eval);
  267. $idString .= "|" . $value;
  268. }
  269. $hash= md5($idString);
  270. #Prado :: trace("$idString: $hash", "Lithron.LImage");
  271. return $hash;
  272. }
  273.  
  274. /**
  275. * Returns file information
  276. */
  277. private function identify($file)
  278. {
  279. $f= "size_short:%b;width:%w;height:%h;type:%m;colorspace:%r;transparent:;resolution_x:%x;resolution_y:%y;colors:%k;quantum:%q;image_depth:%z;";
  280. $cmd= $this->BinPath . "identify -format \"" . $f . "\" '$file'[0]";
  281. exec($cmd, $data);
  282. if (isset ($data[0]))
  283. {
  284. $dataArray= explode(";", $data[0]);
  285. foreach ($dataArray AS $pair)
  286. {
  287. $array= split(":", $pair);
  288. $return[$array[0]]= @ $array[1];
  289. }
  290. return $return;
  291. }
  292. else
  293. {
  294. Prado :: log("Could not identify '" . $file . "'", 3, "Lithron.LImage");
  295. }
  296.  
  297. }
  298.  
  299. /**
  300. * Converts image
  301. */
  302. private function convert($src, $dest)
  303. {
  304. $page= "0";
  305. $cmd= $this->BinPath . "convert ";
  306.  
  307. switch ($this->Info["type"])
  308. {
  309. // change output type for special image formats
  310. case "PSD" :
  311. case "PDF" :
  312. case "PS" :
  313. $this->setDestType("PNG");
  314. $cmd .= " -density 144x144 \"{$src}[{$page}]\" ";
  315. #$cmd .= " -resample 72x72 ";
  316. break;
  317.  
  318. default :
  319. $cmd .= " \"{$src}[{$page}]\" ";
  320. }
  321.  
  322. if ($this->Info['transparent'])
  323. $cmd .= " -colorspace transparent ";
  324.  
  325. if ($this->Info["colorspace"] == "CMYK")
  326. {
  327. echo "COLORSPACE CONVERSION<br>";
  328. $cmd .= "-profile \"" . dirname(__FILE__) . "/EuroscaleUncoated.icc\" ";
  329. $cmd .= "-profile \"" . dirname(__FILE__) . "/sRGB.icm\" ";
  330. $cmd .= "-colorspace RGB";
  331. }
  332. if ($this->getDestWidth() || $this->getDestHeight())
  333. {
  334. $cmd .= " -geometry {$this->getDestWidth()}x{$this->getDestHeight()} ";
  335. }
  336. if ($this->getDestBackgroundColor() !== null)
  337. {
  338. $cmd .= " -background {$this->getDestBackgroundColor()} ";
  339. }
  340.  
  341. $cmd .= " +profile \"*\" -quality {$this->getDestQuality()} ";
  342.  
  343. if ($this->getDestType())
  344. {
  345. $cmd .= " {$this->getDestType()}:";
  346. }
  347. $cmd .= "\"{$dest}\" ";
  348.  
  349. Prado :: trace("executing $cmd", "Lithron.Limage");
  350.  
  351. exec($cmd, $output);
  352. #var_dump($output);
  353. }
  354.  
  355. /**
  356. * Tries to create an image from file extension and mimetype images
  357. */
  358. private function generateAlternativeImage($src, $dest)
  359. {
  360. $mimeIcon= "mimetypes/" . $this->SrcExt . ".png";
  361. if (is_file(dirname(__FILE__) . "/" . $mimeIcon))
  362. {
  363. $altImg= $this->publishAsset($mimeIcon);
  364. }
  365. else
  366. {
  367. $altImg= $this->publishAsset("mimetypes/mime-empty.png");
  368. }
  369. $this->convert(realpath($altImg), $dest);
  370. $this->setImageUrl($dest);
  371. return;
  372.  
  373. $cmd= $this->BinPath . "convert ";
  374. $cmd .= "-background white -fill gray ";
  375. #$cmd .= "-font Arial ";
  376. $cmd .= "-pointsize 24 label:{$this->SrcExt} ";
  377. $cmd .= "{$dest} ";
  378. Prado :: trace("executing $cmd", "Lithron.Limage");
  379.  
  380. exec($cmd, $output);
  381. }
  382. }

Documentation generated on Tue, 20 Jun 2006 05:15:12 +0200 by phpDocumentor 1.3.0RC4