Phundament-Components
[ class tree: Phundament-Components ] [ index: Phundament-Components ] [ 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: 625 $  $Date: 2007-02-25 02:05:09 +0100 (Sun, 25 Feb 2007) $
  11.  * @package Phundament.Components
  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.  * @subpackage Graphics
  20.  * @todo define max dimensions for image rendering!!! PERFORMANCE & MEMORY
  21.  */
  22. class LImage extends TImage
  23. {
  24.     private $SrcUrl;
  25.     private $SrcRealpath;
  26.     private $DestUrl;
  27.     private $DestRealpath;
  28.     private $OutputDir;
  29.     private $SrcExt;
  30.  
  31.     private $BinPath;
  32.     private $Info;
  33.  
  34.     // TODO (PRADO hotfix?)
  35.     
  36.     /**
  37.      * @return string the URL of the image file
  38.      */
  39.     public function getImageUrl()
  40.     {
  41.         return TPropertyValue :: ensureString($this->getViewState('ImageUrl'''));
  42.     }
  43.  
  44.     /**
  45.      * @param string the URL of the image file
  46.      */
  47.     public function setImageUrl($value)
  48.     {
  49.         $this->setViewState('ImageUrl'$value'');
  50.     }
  51.  
  52.  
  53.  
  54.     public function setResize($value)
  55.     {
  56.         $this->setViewState('Resize'TPropertyValue :: ensureBoolean($value)'');
  57.     }
  58.     public function getResize()
  59.     {
  60.         return $this->getViewState('Resize'true);
  61.     }
  62.  
  63.     public function setDestWidth($value)
  64.     {
  65.         $this->setViewState('DestWidth'TPropertyValue :: ensureInteger($value)'');
  66.     }
  67.     public function getDestWidth()
  68.     {
  69.         return $this->getViewState('DestWidth');
  70.     }
  71.  
  72.     public function setDestHeight($value)
  73.     {
  74.         $this->setViewState('DestHeight'TPropertyValue :: ensureInteger($value)'');
  75.     }
  76.     public function getDestHeight()
  77.     {
  78.         return $this->getViewState('DestHeight');
  79.     }
  80.  
  81.     public function setDestQuality($value)
  82.     {
  83.         $this->setViewState('DestQuality'TPropertyValue :: ensureInteger($value)'');
  84.     }
  85.     public function getDestQuality()
  86.     {
  87.         return $this->getViewState('DestQuality'"50");
  88.     }
  89.  
  90.     public function setDestType($value)
  91.     {
  92.         $this->setViewState('DestType'TPropertyValue :: ensureString(strtoupper($value))'');
  93.     }
  94.     public function getDestType()
  95.     {
  96.         return $this->getViewState('DestType''jpg');
  97.     }
  98.  
  99.     public function setDestColorSpace($value)
  100.     {
  101.         $this->setViewState('DestColorSpace'TPropertyValue :: ensureString($value)'');
  102.     }
  103.     public function getDestColorSpace()
  104.     {
  105.         return $this->getViewState('DestColorSpace'"rgb");
  106.     }
  107.  
  108.     public function setShowMimeTypeImage($value)
  109.     {
  110.         $this->setViewState('ShowMimeTypeImage'TPropertyValue :: ensureBoolean($value)'');
  111.     }
  112.     public function getShowMimeTypeImage()
  113.     {
  114.         return $this->getViewState('ShowMimeTypeImage'false);
  115.     }
  116.     public function setDestBackgroundColor($value)
  117.     {
  118.         $this->setViewState('BackgroundColor'TPropertyValue :: ensureString($value)'');
  119.     }
  120.     public function getDestBackgroundColor()
  121.     {
  122.         return $this->getViewState('BackgroundColor'null);
  123.     }
  124.     public function setPageNumber($value)
  125.     {
  126.         $this->setViewState('PageNumber'TPropertyValue :: ensureInteger($value)0);
  127.     }
  128.     public function getPageNumber()
  129.     {
  130.         return $this->getViewState('PageNumber'0);
  131.     }
  132.  
  133.     public function setIsRendered($value)
  134.     {
  135.         $this->setViewState('IsRendered'TPropertyValue :: ensureBoolean($value)false);
  136.     }
  137.     public function getIsRendered()
  138.     {
  139.         return $this->getViewState('IsRendered'false);
  140.     }
  141.  
  142.     public function setPxEmFactor($value)
  143.     {
  144.         $this->setViewState('PxEmFactor'$value);
  145.     }
  146.     public function getPxEmFactor()
  147.     {
  148.         return $this->getViewState('PxEmFactor'false);
  149.     }
  150.  
  151.     public function getAbortRemainingExecutionTime()
  152.     {
  153.         if ($t$this->Application->Parameters['AbortRemainingExecutionTime'])
  154.             return $t;
  155.         else
  156.             return 5;
  157.     }
  158.  
  159.     /**
  160.      * @ignore
  161.      */
  162.     public function onInit($param)
  163.     {
  164.         #Prado :: trace("LImage onInit starting ... ", "Lithron.LImage");
  165.         $param$this->Application->getParameters();
  166.         $this->OutputDir$param->itemAt("OutputDir");
  167.         parent :: onInit($param);
  168.         #Prado :: trace("LImage onInit complete", "Lithron.LImage");
  169.     }
  170.  
  171.     function __construct()
  172.     {
  173.         $this->findImageMagick();
  174.         if (empty ($this->BinPath))
  175.         {
  176.             Prado :: log("ImageMagick not found"32"Lithron.LImage");
  177.             return;
  178.         }
  179.     }
  180.  
  181.     /**
  182.      * @todo double
  183.      */
  184.     public function onLoad($param)
  185.     {
  186.         parent :: onLoad($param);
  187.         #$this->work();
  188.     }
  189.  
  190.     /**
  191.      * @todo double
  192.      */
  193.     public function onPreRender($param)
  194.     {
  195.         parent :: onPreRender($param);
  196.  
  197.         // check if we should abort rendering
  198.         $settings$this->Application->getModule("php_settings");
  199.         if ($settings instanceof TModule)
  200.         {
  201.             $t$settings->getRemainingExecutionTime();
  202.             $at$this->getAbortRemainingExecutionTime();
  203.  
  204.             if ($t $at)
  205.             {
  206.                 $this->Controls[]"image not yet rendered";
  207.                 $this->ImageUrl"_IMAGE_NOT_YET_RENDERED_";
  208.                 Prado :: log("Rendering abortedonly $t sec(stime left"TLogger :: INFO"Lithron.LImage");
  209.                 return;
  210.             }
  211.         }
  212.  
  213.         // assume rendered image when url points to tmp path, otherwise postback problems
  214.         if (!strstr($this->ImageUrl$this->OutputDir))
  215.         {
  216.             $this->work();
  217.  
  218.             // TODO
  219.             try
  220.             {
  221.                 #    $this->ImageUrl;
  222.                 $infogetimagesize($this->Application->BasePath "/../" $this->ImageUrl);
  223.                 #$this->PxEmFactor = 12;
  224.                 if ($this->PxEmFactor)
  225.                 {
  226.                     $this->Width($info[010"em";
  227.                     $this->Height($info[110"em";
  228.                 }
  229.                 else
  230.                 {
  231.                     $this->Width$info[0];
  232.                     $this->Height$info[1];
  233.                 }
  234.             }
  235.             catch (Exception $e)
  236.             {
  237.                 Prado :: log($e->getMessage()2"Lithron.LImage");
  238.             }
  239.         }
  240.         else
  241.         {
  242.  
  243.         }
  244.  
  245.     }
  246.  
  247.     private function work()
  248.     {
  249.         if (empty ($this->BinPath))
  250.         {
  251.             return;
  252.         }
  253.         if ($this->getResize(== true && $this->getImageUrl())
  254.         {
  255.             $this->generateImage();
  256.         }
  257.         else
  258.             if ($this->getImageUrl())
  259.             {
  260.                 // todo;
  261.                 try
  262.                 {
  263.                     $publishedUrl$this->publishFilePath($this->getImageUrl());
  264.  
  265.                     $this->setImageUrl($publishedUrl);
  266.                     $this->IsRenderedtrue;
  267.                 }
  268.                 catch (Exception $e)
  269.                 {
  270.                     Prado :: log($e->getMessage()8);
  271.                 }
  272.             }
  273.     }
  274.  
  275.     public function doIdentify($file)
  276.     {
  277.         return $this->identify($file);
  278.     }
  279.  
  280.     /**
  281.     * Searches ImageMagick in file system
  282.     */
  283.     private function findImageMagick()
  284.     {
  285.         if ($this->BinPath$this->Application->getGlobalState("LImage:BinPath"))
  286.         {
  287.             putenv("PATH=" $this->BinPath);
  288.             return;
  289.         }
  290.  
  291.         $param$this->Application->getParameters();
  292.         $pathsexplode(";"$param->itemAt("ImagickSearchPaths"));
  293.         foreach ($paths AS $path)
  294.         {
  295.             if (!is_dir($path))
  296.                 continue;
  297.             #echo $path;exit;
  298.             exec($path "/identify -version"$output);
  299.             if (isset ($output[0]&& strstr($output[0]"ImageMagick"))
  300.             {
  301.                 $this->BinPath$path "/";
  302.                 $this->Application->setGlobalState("LImage:BinPath"$this->BinPath);
  303.                 return;
  304.                 #break;
  305.             }
  306.             #$this->BinPath;
  307.         }
  308.  
  309.     }
  310.  
  311.     /**
  312.     * Invokes image generation
  313.     */
  314.     private function generateImage()
  315.     {
  316.         #Prado :: trace("Generating image ... ", "Lithron.LImage");
  317.         $this->SrcUrl$this->getImageUrl();
  318.         $this->SrcRealpathrealpath($this->getImageUrl());
  319.         $this->SrcExtsubstr(strrchr($this->SrcUrl".")1);
  320.  
  321.         // check if missing
  322.         if (!is_file($this->SrcUrl))
  323.         {
  324.             Prado :: log("File '" $this->SrcUrl "' missing"8"Lithron.LImage");
  325.             $this->setImageUrl($this->publishAsset("LImage/mimetypes/missing.png"));
  326.             return;
  327.         }
  328.  
  329.         // output folder
  330.         $outputDirrealpath($this->OutputDir);
  331.  
  332.         // check cache
  333.         #$file= $this->generateHash(); #.".".$outputType;
  334.         $file$this->generateHash("." strtolower($this->getDestType());
  335.  
  336.         if (is_file($outputDir "/" $file))
  337.         {
  338.             #Prado :: trace("Using cached file: {$file} <= '{$this->SrcUrl}' ", "Lithron.LImage");
  339.             $this->setImageUrl($this->OutputDir "/" $file);
  340.             return;
  341.         }
  342.  
  343.         // get file info
  344.         $this->Info$this->identify($this->SrcRealpath);
  345.  
  346.         if (is_writable($outputDir))
  347.         {
  348.             $outputRealpath$outputDir "/" $file;
  349.             $clientUrl$this->OutputDir "/" $file;
  350.             // generate image
  351.             if ($this->getShowMimeTypeImage(=== true)
  352.             {
  353.                 $this->generateAlternativeImage($this->SrcRealpath$outputRealpath);
  354.             }
  355.             else
  356.             {
  357.                 $this->convert($this->SrcRealpath$outputRealpath);
  358.                 if (!is_file($outputRealpath))
  359.                 {
  360.                     $this->generateAlternativeImage($this->SrcRealpath$outputRealpath);
  361.                 }
  362.             }
  363.  
  364.             $this->setImageUrl($clientUrl);
  365.         }
  366.         else
  367.         {
  368.             Prado :: log("OutputDir '" $outputDir "' is not writable"3"Lithron.LImage");
  369.         }
  370.  
  371.     }
  372.     /**
  373.     * Creates a unique fingerprint of the destination file
  374.     */
  375.     private function generateHash()
  376.     {
  377.         if ($cache$this->Application->Cache)
  378.         {
  379.             #$idString= $cache->get("LImage:" . $this->SrcUrl);
  380.         }
  381.         if (empty ($idString))
  382.         {
  383.             Prado :: trace("Creating new md5 for {$this->SrcUrl} ...", "Lithron.LImage");
  384.  
  385.             // useless performance debug ? wrong microtimes !?
  386.             if ($this->ShowMimeTypeImage === false)
  387.             {
  388.                 $file_contentsfile_get_contents($this->SrcUrl);
  389.                 #$file_contents = $this->SrcUrl;
  390.                 #sleep(0.1);
  391.                 $idStringmd5($file_contents);
  392.             }
  393.             else
  394.             {
  395.                 $idStringstrrchr($this->SrcUrl".");
  396.             }
  397.  
  398.             #Prado :: trace("Md5 for {$this->SrcUrl} created", "Lithron.LImage");
  399.             if ($cache)
  400.             {
  401.                 $cache->set("LImage:" $this->SrcUrl$idString360);
  402.             }
  403.         }
  404.         $_propsarray (
  405.             "DestWidth",
  406.             "DestHeight",
  407.             "DestType",
  408.             "DestQuality",
  409.             "DestColorSpace",
  410.             "DestBackgroundColor",
  411.             "ShowMimeTypeImage",
  412.             "PageNumber"
  413.         );
  414.  
  415.         foreach ($_props AS $prop)
  416.         {
  417.             $_eval"return(\$this->get" . $prop . "());";
  418.             $value= eval ($_eval);
  419.             $idString .= "|" . $value;
  420.         }
  421.         $hashmd5($idString);
  422.         #Prado :: trace("$idString: $hash", "Lithron.LImage");
  423.         return $hash;
  424.     }
  425.  
  426.     /**
  427.     * Returns file information
  428.     */
  429.     private function identify($file)
  430.     {
  431.         $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;";
  432.         $cmd$this->BinPath . "identify -format \"" . $f . "\" '$file'[0]";
  433.  
  434.         #Prado :: log("Executing $cmd", TLogger :: INFO, "Lithron.Limage");
  435.         exec($cmd, $data);
  436.         if (isset ($data[0]))
  437.         {
  438.             $dataArrayexplode(";", $data[0]);
  439.             foreach ($dataArray AS $pair)
  440.             {
  441.                 $arraysplit(":", $pair);
  442.                 $return[$array[0]]@ $array[1];
  443.             }
  444.             return $return;
  445.         }
  446.         else
  447.         {
  448.             Prado :: log("Could not identify '" . $file . "'", 4, "Lithron.LImage");
  449.         }
  450.  
  451.     }
  452.  
  453. /**    
  454.     * Converts image
  455.     */
  456.     private function convert($src, $dest)
  457.     {
  458.         if (isset ($this->Info['Error']))
  459.         {
  460.             Prado :: log("ImageMagick error: " . $this->Info['Error'], 16, "Lithron.LImage");
  461.             return;
  462.         }
  463.  
  464.         $page= (string)$this->getPageNumber();
  465.         $cmd$this->BinPath . "convert ";
  466.  
  467.         switch ($this->Info["type"])
  468.         {
  469.             // change output type for special image formats
  470.             case "PSD" :
  471.             case "PDF" :
  472.             case "PS" :
  473.                 $this->setDestType("PNG");
  474.                 $cmd .= " -density 144x144 \"{$src}[{$page}]\" ";
  475.                 #$cmd .= " -resample 72x72 ";
  476.                 break;
  477.  
  478.             default :
  479.                 $cmd .= \"{$src}[{$page}]\" ";
  480.         }
  481.  
  482.         if ($this->Info['transparent'])
  483.             $cmd .= " -colorspace transparent ";
  484.  
  485.         if (strstr($this->Info["colorspace"], "CMYK") && $this->DestColorspace != "CMYK")
  486.         {
  487.             #echo "COLORSPACE CONVERSION<br>";
  488.             $cmd .= "-profile \"" . dirname(__FILE__) . "/EuroscaleUncoated.icc\" ";
  489.             $cmd .= "-profile \"" . dirname(__FILE__) . "/sRGB.icm\" ";
  490.             $cmd .= "-colorspace RGB";
  491.         }
  492.         if ($this->getDestWidth() || $this->getDestHeight())
  493.         {
  494.             $cmd .= " -geometry {$this->getDestWidth()}x{$this->getDestHeight()";
  495.         }
  496.         if ($this->getDestBackgroundColor() !== null)
  497.         {
  498.             $cmd .= " -background {$this->getDestBackgroundColor()";
  499.         }
  500.  
  501.         $cmd .= " +profile \"*\" -quality {$this->getDestQuality()";
  502.  
  503.         if ($this->getDestType())
  504.         {
  505.             $cmd .= {$this->getDestType()}:";
  506.         }
  507.         $cmd .= "\"{$dest}\" ";
  508.  
  509.         Prado :: log("Executing $cmd", TLogger :: INFO, "Lithron.Limage");
  510.  
  511.         exec($cmd, $output);
  512.         #var_dump($output);
  513.     }
  514.  
  515.     /**
  516.     * Tries to create an image from file extension and mimetype images
  517.     */
  518.     private function generateAlternativeImage($src, $dest)
  519.     {
  520.         $mimeIcon"LImage/mimetypes/" . $this->SrcExt . ".png";
  521.         if (is_file(dirname(__FILE__) . "/" . $mimeIcon))
  522.         {
  523.             $altImg$this->publishAsset($mimeIcon);
  524.         }
  525.         else
  526.         {
  527.             $altImg$this->publishAsset("LImage/mimetypes/mime-empty.png");
  528.         }
  529.         $this->convert(realpath($altImg), $dest);
  530.         $this->setImageUrl($dest);
  531.         return;
  532.  
  533.         $cmd$this->BinPath . "convert ";
  534.         $cmd .= "-background white -fill gray ";
  535.         #$cmd .= "-font Arial ";
  536.         $cmd .= "-pointsize 24 label:{$this->SrcExt";
  537.         $cmd .= "{$dest";
  538.         Prado :: trace("executing $cmd", "Lithron.Limage");
  539.  
  540.         exec($cmd, $output);
  541.     }
  542. }

Documentation generated on Sun, 25 Feb 2007 16:10:39 +0100 by phpDocumentor 1.3.1