Наскоро ми се наложи да мисля начин как в уебстраница при upload на векторна графика автоматично да й се създава растерен вариант (PNG). На пръв поглед има една камара конзолен софтуер за целта, но при всеки имаше проблеми.

Едното изискване при растеризирането е когато оригиналният вектор е с прозрачен фон, и PNG-то да е прозрачно. Другото изискване е да се спази пропорцията на изображението. Та ей тези две неща все бяха проблемни.

Първо мъчих с convert (ImageMagick) - според документацията му трябва безпроблемно да се справя с растеризиране на EPS и AI формати (посредством ghostscript), което за съжаление не беше така - не се запазваше прозрачността. След дълго главоблъскане установих, че всъщност convert подава грешен параметър "sDEVICE" към ghostscript ("pnmraw" вместо "pngalpha"). Очевидно решението беше да работя директно с ghostscript без да минавам през convert. Това пък ме затрудняваше, щото нямаше как да задам коректно размерите в пиксели, в които искам растерния файл. Наложи се всеки път чрез identify (ImageMagick) да взимам резолюцията на изображението, за да изчисля пропорцията. С това проблемът с EPS форматът беше решен (AI така и не успях да подкарам, и аз не знам защо).

Паралелно с това, исках чрез inkscape да правя същото със SVG и SVGZ файлове. За съжаление се оказа, че наистина трябва да правя същото (проблемът със запазването на пропорцията). Тук обаче identify не можеше да помогне с намирането на резолюцията и трябваше сам да прочитам първите еди-колко-си реда от файла, за да намеря пропорцията.

И тъй като наистина ми беше много зор докато стигна до някакъв задоволителен работещ вариант, мисля да го споделя...

define( 'GHOSTSCRIPT',      '/usr/local/bin/gs' );
define( 'INKSCAPE',      '/usr/bin/inkscape' );
define( 'IDENTIFY',      '/usr/local/imagemagick/bin/identify' );
function rasterize_eps($source, $destination_png, $w=FALSE, $h=FALSE)
{
      if( FALSE == file_exists($source) ) {
            return FALSE;
      }
      $w      = intval( $w );
      $h      = intval( $h );
      $in_cmd      = '';
      if( $w>0 && $h>0 ) {
            $file_w      = FALSE;
            $file_h      = FALSE;
            $res_x      = FALSE;
            $res_y      = FALSE;
            exec( IDENTIFY.' -verbose '.$source.' | grep "x" ', $output );
            foreach( $output as $line ) {
                  if( preg_match( '/Geometry:s([0-9]+)x([0-9]+)(+|-)/', $line, $matches ) ) {
                        $file_w      = intval( $matches[1] );
                        $file_h      = intval( $matches[2] );
                  }
                  if( preg_match( '/Resolution:s([0-9]+)x([0-9]+)/', $line, $matches ) ) {
                        $res_x      = intval( $matches[1] );
                        $res_y      = intval( $matches[2] );
                  }
                  if( FALSE!=$file_w && FALSE!=$file_h && FALSE!=$res_x && FALSE!=$res_y ) {
                        break;
                  }
            }
            if( intval($file_w)>0 && intval($file_h)>0 && intval($res_x)>0 && intval($res_y)>0 && $res_x==$res_y ) {
                  if( $file_w/$file_h > $w/$h  ) {
                        $res_x      *= $w / $file_w;
                        $res_y      = $res_x;
                  }
                  else {
                        $res_y      *= $h / $file_h;
                        $res_x      = $res_y;
                  }
                  $res_x      = round( $res_x, 5 );
                  $res_y      = round( $res_y, 5 );
                  $in_cmd      = '-r'.$res_x.'x'.$res_y;
            }
      }
      $command      = GHOSTSCRIPT.' -dNOPAUSE -dQUIET -dBATCH -sDEVICE=pngalpha '.$in_cmd.' -dEPSCrop -sOutputFile='.$destination_png.' '.$source;
      exec( $command );
      if( FALSE == file_exists($destination_png) ) {
            return FALSE;
      }
      chmod($destination_png, 0777);
      return TRUE;
}
function rasterize_svg($source, $destination_png, $w=FALSE, $h=FALSE)
{
      if( FALSE == file_exists($source) ) {
            return FALSE;
      }
      $w      = intval( $w );
      $h      = intval( $h );
      $in_cmd      = '--export-width='.$w;
      if( $w>0 && $h>0 && preg_match('/.svg$/i', $source) ) {
            $file_w      = FALSE;
            $file_h      = FALSE;
            $handle      = fopen($source, 'r');
            $i      = 0;
            $j      = 6;
            while( FALSE==feof($handle) && $i++<$j ) {
                  $line      = strtolower( fgets( $handle ) );
                  if( FALSE !== strpos( $line, 'viewbox' ) ) {
                        $line      = str_replace( array('"', '''), '', $line );
                        preg_match( '/viewbox(s)?=(s)?('|\")?([0-9.,]+)s([0-9.,]+)s([0-9.,]+)s([0-9.,]+)('|\")?/', $line, $matches );
                        $file_w      = floatval( $matches[6] );
                        $file_h      = floatval( $matches[7] );
                        break;
                  }
                  $line      = trim($line);
                  if( empty($line) || preg_match('/^<!--.*-->$/', $line) ) {
                        $j      ++;
                  }
            }
            fclose($handle);
            if( intval($file_w)&gt;0 &amp;&amp; intval($file_h)&gt;0 ) {
                  $in_cmd      = $file_w/$file_h&gt;$w/$h ? ( '--export-width='.$w ) : ( '--export-height='.$h );
            }
      }
      elseif( $w&gt;0 &amp;&amp; $h&gt;0 &amp;&amp; preg_match('/.svgz$/i', $source) ) {
            $file_w      = FALSE;
            $file_h      = FALSE;
            $handle      = gzopen($source, 'r');
            $i      = 0;
            $j      = 6;
            while( FALSE==gzeof($handle) &amp;&amp; $i++&lt;$j ) {
                  $line      = strtolower( gzgets( $handle ) );
                  if( FALSE !== strpos( $line, 'viewbox' ) ) {
                        $line      = str_replace( array('"', '''), '', $line );
                        preg_match( '/viewbox(s)?=(s)?('|\")?([0-9.,]+)s([0-9.,]+)s([0-9.,]+)s([0-9.,]+)('|\")?/', $line, $matches );
                        $file_w      = floatval( $matches[6] );
                        $file_h      = floatval( $matches[7] );
                        break;
                  }
                  $line      = trim($line);
                  if( empty($line) || preg_match('/^<!--.*-->$/', $line) ) {
                        $j      ++;
                  }
            }
            gzclose($handle);
            if( intval($file_w)&gt;0 &amp;&amp; intval($file_h)&gt;0 ) {
                  $in_cmd      = $file_w/$file_h&gt;$w/$h ? ( '--export-width='.$w ) : ( '--export-height='.$h );
            }
      }
      $command      = INKSCAPE.' --without-gui --file='.$source.' --export-area-drawing '.$in_cmd.' --export-png='.$destination_png;
      exec( $command );
      if( FALSE == file_exists($destination_png) ) {
            return FALSE;
      }
      chmod($destination_png, 0777);
      return TRUE;
}

Tags: , , , , , , , , ,

Leave a Reply



Recently Commented