Advertisement
Guest User

Untitled

a guest
Apr 3rd, 2012
484
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 15.90 KB | None | 0 0
  1. <?
  2.  
  3.     // file
  4.     // - src - src
  5.     // - new - new file name
  6.     // - mode - generate mode = выяснить что я имел ввиду :)
  7.  
  8.     class images
  9.     {
  10.         var $srt = array
  11.             (
  12.                 'ic',
  13.                 'time_create desc',
  14.                 'time_update desc',
  15.             );
  16.  
  17.  
  18.         function images()
  19.         {
  20.           global $conf;
  21.           $this->conf = $conf;
  22.           $this->clear();
  23.         }
  24.  
  25.         function clear()
  26.         {
  27.             $this->id = 0;
  28.             $this->value = array
  29.             (
  30.                 'ic'        => '',
  31.                 'info'        => '',
  32.                 'descr'        => '',
  33.                 'file'        => false,
  34.                 'hash'        => 'undefined',
  35.                 'chash'        => 'undefined',
  36.             );
  37.             $this->set_ctype(0);
  38.         }
  39.  
  40.         // 0 - ok
  41.         // 1 - file error
  42.         // 2 - not image
  43.         // 3 - exist
  44.         function set_file($fn)
  45.         {
  46.       $v = &$this->value;
  47.             $v['file'] = $fn;
  48.             return 0;
  49.         }
  50.  
  51.         function set_ctype($t)
  52.         {
  53.             if (!isset($this->conf['image_ctypes'][$t]))
  54.             {
  55.                 reset($this->conf['image_ctypes']);
  56.                 $t = key($this->conf['image_ctypes']);
  57.             }
  58.             $this->value['ctype'] = $t;
  59.         }
  60.  
  61.         // value
  62.         // - ctype
  63.         // - ic
  64.         function save()
  65.         {
  66.  
  67.             $v = &$this->value;
  68.             if (false === $v['file'])
  69.             {
  70.                 return $this->_err('no file');
  71.             }
  72.             if(false === ($im = $this->_open($v['file']) ) )
  73.                 return $this->_err('error opening' );
  74.             if( false === ($fn = $this->_generate($im)) )
  75.                 return $this->_err('error generating');
  76.             return true;
  77.         }
  78.  
  79.         function _generate($im)
  80.         {
  81.             $v = &$this->value;
  82.  
  83.             // generate tmp files
  84.             $fl = array();
  85.             $ok = true;
  86.             $st = $this->conf['image_ctypes'][$v['ctype']][2];
  87.             $j = 100/count($st);
  88.             $k = 0;
  89.  
  90.             foreach ($st as $i=>$s)
  91.             {
  92.               if (false === ($fn = $this->_convert($im, $s)))
  93.               {
  94.                 return $this->_err('error converting');
  95.               }
  96.               rename($fn, dirname($im[3]) . '/' . basename($im[3], strrchr($im[3], '.'))  . '_' . $i . $this->_getExtension($im[0]));
  97.             }
  98.         }
  99.  
  100.         // open image
  101.         function _open($fn)
  102.         {
  103.             $i = "Image:";
  104.             if (false === ($s = $this->_exec('identify', '-verbose '.$fn))
  105.                 || false === ($p = strpos($s, $i)))
  106.                 //|| !preg_match_all('/^[^ ]+ ([^ ]+) (\d+)x(\d+)/m', substr($s, 0, $p), $m))
  107.             {
  108.                 return false;
  109.             }
  110.             $s = substr($s, $p);
  111.             $s = preg_replace('/^\s+(\d+):/m', '    $1:', $s);
  112.             if (0 == preg_match_all('/^( *)([^:]+):(?: (.*))?$/m', $s, $m, PREG_SET_ORDER))
  113.             {
  114.                 return false;
  115.             }
  116.             $j = array();
  117.             $t = array(&$j);
  118.             for (reset($m), $x = '', $l = 0; $c = current($m); next($m))
  119.             {
  120.                 if (0 == ($d = strlen($c[1]))
  121.                     && $i != $c[2].':')
  122.                 {
  123.                     continue;
  124.                 }
  125.                 if ($d > $l)
  126.                 {
  127.                     $t[$l][$x] = array();
  128.                     $t[$d] = &$t[$l][$x];
  129.                 }
  130.                 $x = 0 == $d ? count($t[$d]) : strtolower($c[2]);
  131.                 if (isset($c[3]))
  132.                 {
  133.                     $t[$d][$x] = $c[3];
  134.                 }
  135.                 $l = $d;
  136.             }
  137.             foreach ($j as $i=>$v)
  138.             {
  139.                 if (isset($v['delay']))
  140.                 {
  141.                     $v['delay'] = intval($v['delay']);
  142.                 }
  143.             }
  144.             if (false === ($f = reset($j))
  145.                 || !isset($f['format'])
  146.                 || !isset($f['geometry'])
  147.                 || !preg_match('/^(\d+)x(\d+)([^ ]+)/', $f['geometry'].$f['format'], $m))
  148.             {
  149.                 return false;
  150.             }
  151.             return array
  152.             (
  153.                 0    => $m[3],                    // format
  154.                 1    => array_slice($m, 1, 2),    // x y
  155.                 2    => $j,                        // info
  156.                 3    => $fn,                        // file name
  157.             );
  158.         }
  159.  
  160.         function _exec($c, $a)
  161.         {
  162.             $d = array
  163.             (
  164.                 0    => array('pipe',    'r'),
  165.                 1    => array('pipe',    'w'),
  166.                 2    => array('pipe',    'w'),
  167.             );
  168.             $p = array
  169.             (
  170.                 'convert'    => $this->conf['imagick_dir'],
  171.                 'identify'    => $this->conf['imagick_dir'],
  172.                 'gifsicle'    => $this->conf['gifsicle_dir'],
  173.             );
  174.             $p = isset($p[$c]) ? $p[$c] : '';
  175.             $h = proc_open('nice ' . $p.$c.' '.$a, $d, $p);
  176.             if (!is_resource($h))
  177.             {
  178.                 return $this->_err('unable to exec');
  179.             }
  180.             $s = array_fill(0, 2, '');
  181.             fwrite($p[$l = 0], '');
  182.             fclose($p[$l++]);
  183.             for ($i = 0; $i < 2; $i++)
  184.             {
  185.                 while (!feof($p[$l])
  186.                     && ($v = fgets($p[$l], 1024)))
  187.                 {
  188.                     $s[$i].= $v;
  189.                 }
  190.                 fclose($p[$l++]);
  191.             }
  192.             //echo '- EXEC ['.$c."]\n";
  193.             return 0 !== ($r = proc_close($h)) ? false : $s[0];
  194.         }
  195.  
  196.         // u - unit
  197.         // s - settings
  198.         function _convert($u, $s)
  199.         {
  200.             if (5 != count($s)
  201.                 || false === ($f = $this->_parse_format($u[0]))
  202.                 || false === ($m = $this->_parse_mode($u[1], $s[1]))
  203.                 || false === ($h = $this->_parse_mark($s[2]))
  204.                 || false === ($g = $this->_parse_color($s[3]))
  205.                 || false === ($b = $this->_parse_border($s[4])))
  206.             {
  207.                 return $this->_err('error parsing file formats');
  208.             }
  209.             $t = $u[1];
  210.             $z = $m[1][0]/$m[1][1] > $u[1][0]/$u[1][1] ? 0 : 1;
  211.             $t[1 - $z] = max($m[1][1 - $z]/$m[1][$z]*$u[1][$z], $u[1][1 - $z] - 2*$m[2][1 - $z]);
  212.             if (0 == $m[0])
  213.             {
  214.                 for ($q = array(), $i = 0; $i < 2; $i++)
  215.                 {
  216.                     array_push($q, min($t[$i], $m[1][$i]));
  217.                 }
  218.             }
  219.             else
  220.             {
  221.                 $z = $t[0]/$t[1] > $m[1][0]/$m[1][1] ? 0 : 1;            // in box
  222.                 for ($q = array(), $i = 0; $i < 2; $i++)
  223.                 {
  224.                     array_push($q, min(1, $m[1][$z]/$t[$z])*$t[$i]);
  225.                 }
  226.             }
  227.             for ($w = array(), $i = 0; $i < 2; $i++)                    // cutting
  228.             {
  229.                 //$t[$i] = round($t[$i]);
  230.                 $q[$i] = round($q[$i]);
  231.                 $w[$i] = floor(($u[1][$i] - $t[$i])/2);
  232.             }
  233.             $c = '';                                                    // command
  234.  
  235.       if ('' != $m[4])
  236.       {
  237.         $c.= '-rotate '.$m[4].'90 ';
  238.       }
  239.  
  240.             if (0 < max($w))
  241.             {
  242.                 $c.= '-shave '.implode('x', $w).' ';//.' +repage ';
  243.             }
  244.             if ($q != $u[1])
  245.             {
  246.                 $c.= '-filter Box -resize '.implode('x', $q).'! ';
  247.             }
  248.             $w = array_fill(0, 2, array());                                // background
  249.             for ($i = 0; $i < 2; $i++)
  250.             {
  251.                 $x = (1 == $m[0] ? $m[1][$i] - $q[$i] : 0) + 2*$m[3][$i];
  252.                 $x-= ($y = floor($x/2));
  253.                 array_push($w[0], floor($x));
  254.                 array_push($w[1], $y);
  255.             }
  256.             foreach ($w as $i=>$v)
  257.             {
  258.                 if (0 < max($v))
  259.                 {
  260.                     $c.= '' != $g ? '-background '.$g.' ' : '';
  261.                     $c.= '-gravity '.(0 == $i ? 'northwest' : 'southeast');
  262.                     $c.= ' -splice '.implode('x', $v).' ';
  263.                 }
  264.             }
  265.             if (0 < max($b[0]))                                            // border
  266.             {
  267.                 $c.= '' != $b[1] ? '-bordercolor '.$b[1].' ' : '';
  268.                 $c.= '-border '.implode('x', $b[0]).' ';
  269.             }
  270.             if ('' != $h[0])
  271.             {
  272.                 $c.= '-gravity '.$h[1].' '.$h[0].' -compose src-over -composite ';
  273.             }
  274.             if (false === ($t = tempnam('/tmp', 'image_')))
  275.             {
  276.                 return $this->_err('error creating temp file');
  277.             }
  278.             if (1 == ($j = count($u[2]))
  279.                 || false === $f[0])
  280.             {
  281.                 $s = $u[3].' '.(1 != $j ? ' -delete 1-'.($j - 1).' ' : '').$c.' '.$f[1].':'.$t;
  282.                 if (false !== $this->_exec('convert', $s)
  283.                     && false !== chmod($t, 0666))
  284.                 {
  285.                     return $t;
  286.                 }
  287.             }
  288.             else
  289.             {
  290.                 $s = '-coalesce ';
  291.                 foreach ($u[2] as $i=>$v)
  292.                 {
  293.                     $s.= isset($v['delay']) ? '-delay '.$v['delay'].' ' : '';
  294.                     //$s.= isset($v['background color']) ? '-set background '.$v['background color'].' ' : '';
  295.                     //$s.= '-set transparent white ';
  296.                     //$s.= isset($v['transparent color']) ? '-transparent '.$v['transparent color'].' ' : '';
  297.                     $s.= '\( -coalesce '.$u[3].' ';
  298.                     $s.= $j != $i + 1 ? '-delete '.($i + 1).'--1 ' : '';
  299.                     $s.= 0 != $i ? '-compose copy -delete 0'.($i > 1 ? '-'.($i - 1) : '').' ' : '';
  300.                     $s.= $c.'\) ';
  301.                 }
  302.                 $s.= '-fuzz 7% -layers compare-any MIFF:'.$t;
  303.                 //$s.= '-fuzz 7% -layers OptimizePlus MIFF:'.$t;
  304.                 if (false !== $this->_exec('convert', $s))
  305.                 {
  306.                     $s = $t.' +append -quantize rgb ';// transparent ';
  307.                     $s.= '-unique-colors -colors 256 MIFF:'.$t.'map';
  308.                     if (false !== $this->_exec('convert', $s))
  309.                     {
  310.                         $s = $t.' -map '.$t.'map '.$f[1].':'.$t;
  311.                         if (false !== $this->_exec('convert', $s)
  312.                             && false !== chmod($t, 0666))
  313.                         {
  314.                             unlink($t.'map');
  315.                             if (false === strpos($f[1], 'GIF')
  316.                                 || false !== $this->_exec('gifsicle', '-O2 '.$t.' -o '.$t))
  317.                             {
  318.                                 return $t;
  319.                             }
  320.                         }
  321.                         unlink($t.'map');
  322.                     }
  323.                 }
  324.             }
  325.             unlink($t);
  326.             return false;
  327.         }
  328.  
  329.         function _parse_mark($s)
  330.         {
  331.             if (false === ($p = strpos($s, '/')))
  332.             {
  333.                 $x = 'east';
  334.             }
  335.             else
  336.             {
  337.                 $x = substr($s, $p + 1);
  338.                 $s = substr($s, 0, $p);
  339.             }
  340.             return array
  341.             (
  342.         //TODO: add dir to образец image
  343.                 0    => $s ? /*fs::path('var/src').*/$s : '',
  344.                 1    => $x,
  345.             );
  346.         }
  347.  
  348.         function _parse_border($s)
  349.         {
  350.             $s = explode('/', $s);
  351.             $s = array_pad($s, 2, '');
  352.             if ($s[0] == $s[1]
  353.                 && '' == $s[0])
  354.             {
  355.                 return array(array(0, 0), '');
  356.             }
  357.             return false === ($c = $this->_parse_color($s[1]))
  358.                 || false === ($x = $this->_parse_xy(array(1, 1), $s[0]))
  359.                 ? $this->_err('error parsing border')
  360.                 : array($x, $c);
  361.         }
  362.  
  363.         function _parse_color($s)
  364.         {
  365.             if (0 == strlen($s))
  366.             {
  367.                 return '';
  368.             }
  369.             elseif ((3 != ($c = count($s = explode(',', $s)))
  370.                     && 4 != $c)
  371.                 || 255 < max($s)
  372.                 || 0 > min($s))
  373.             {
  374.                 return $this->_err('parse color error');
  375.             }
  376.             $s = 'rgb'.(4 == $c ? 'a' : '').'\('.implode(',', $s).'\)';
  377.             return $s;
  378.         }
  379.  
  380.         function _parse_xy($b, $s)
  381.         {
  382.             $s = explode('x', $s, 2);
  383.             if (1 == count($s))
  384.             {
  385.                 array_push($s, $s[0]);
  386.             }
  387.             $r = array();
  388.             $j = false;
  389.             foreach ($s as $i=>$c)
  390.             {
  391.                 if (0 == strlen($c))
  392.                 {
  393.                     array_push($r, false);
  394.                     $j = $i;
  395.                 }
  396.                 elseif ('%' == $c{0})
  397.                 {
  398.                     $c = substr($c, 1);
  399.                     if (!is_numeric($c)
  400.                         || $c < 0)
  401.                     {
  402.                         return $this->_err('parse XY (percents) error');
  403.                     }
  404.                     array_push($r, $c/100*$b[$i]);
  405.                 }
  406.                 else
  407.                 {
  408.                     if (!is_numeric($c)
  409.                         || $c < 0)
  410.                     {
  411.                         return $this->_err('parse XY error');
  412.                     }
  413.                     array_push($r, intval($c));
  414.                 }
  415.             }
  416.             if (false !== $j)
  417.             {
  418.                 if ($r[0] === $r[1])
  419.                 {
  420.                     return $b;
  421.                 }
  422.                 $r[$j] = $r[1 - $j]/$b[1 - $j]*$b[$j];
  423.             }
  424.             return $r;
  425.         }
  426.  
  427.         function _parse_format($s)
  428.         {
  429.             $m = array
  430.             (
  431.                 'GIF'    => array(true,    true,    'GIF'),
  432.                 'GIF87'    => array(true,    false,    'GIF87'),
  433.                 'JPEG'    => array(true,    false,    '-quality 90 JPEG'),
  434.             );
  435.             return !isset($m[$s])
  436.                 || true !== $m[$s][0]
  437.                 ? $this->_err('error parsing file format') : array_slice($m[$s], 1);
  438.         }
  439.  
  440.     function _getExtension($format)
  441.     {
  442.       switch ($format)
  443.       {
  444.         case 'GIF':
  445.         case 'GIF87':
  446.           return '.gif';
  447.         case 'JPEG':
  448.           return '.jpg';
  449.       }
  450.     }
  451.  
  452.     function _parse_mode(&$b, $s)
  453.     {
  454.       $s = explode('/', $s);
  455.       $s = array_pad($s, 4, '');
  456.       $r = array();    // result
  457.       $m = array      // modes
  458.       (
  459.         's'  => 0,    // simple resize
  460.         '='  => 1,    // inscribe
  461.         '~'  => 2,    // ?
  462.       );
  463.       if (0 != strlen($s[0])
  464.         && isset($m[$s[0]{0}]))
  465.       {
  466.         array_push($r, $m[$s[0]{0}]);
  467.         $s[0] = substr($s[0], 1);
  468.       }
  469.       else
  470.       {
  471.         array_push($r, reset($m));
  472.       }
  473.       $j = $this->_parse_xy($b, reset($s));
  474.       $m = array
  475.       (
  476.         '+',
  477.         '-',
  478.       );
  479.       if (in_array($d = array_pop($s), $m)
  480.         && (($j[0]/$j[1] < 1 && $b[0]/$b[1] > 1) || ($j[0]/$j[1] > 1 && $b[0]/$b[1] < 1)))
  481.       {
  482.         $b = array_reverse($b);
  483.       }
  484.       else
  485.       {
  486.         $d = '';
  487.       }
  488.       do
  489.       {
  490.         array_push($r, $j);
  491.       }
  492.       while (false !== ($c = next($s))
  493.         && false !== ($j = $this->_parse_xy($b, $c)));
  494.       array_push($r, $d);
  495.       return 5 == count($r)
  496.         ? $r
  497.         : $this->_err('parse mode error');
  498.     }
  499.  
  500.  
  501.     function _err($error)
  502.     {
  503. //      logRequest($error, false);
  504.       logRequest($error . ' ' . $this->value['file'], false);
  505.       return false;
  506.     }
  507.   }
  508.  
  509. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement