Convertir imagen SVG a PNG con PHP

Estoy trabajando en un proyecto web que consiste en un generadas dinámicamente mapa de los estados unidos para colorear diferentes estados a partir de un conjunto de datos.

Este archivo SVG, me da un buen mapa en blanco de los EE.UU. y es muy fácil cambiar el color de cada estado. La dificultad es que el IE, navegadores no soportan SVG así, para mí el uso de la mano de la sintaxis de la svg ofrece, me será necesario convertirlo a un archivo JPG.

Idealmente, me gustaría hacer esto con sólo el GD2 biblioteca, pero también podría usar ImageMagick. No tengo absolutamente ni idea de cómo hacerlo.

Cualquier solución que me permitiera cambiar dinámicamente los colores de los estados en un mapa de los estados unidos, serán considerados. La clave es que es fácil de cambiar los colores sobre la marcha y que es la cruz del navegador. PHP/Apache sólo las soluciones, por favor.

  • hay clases diseñadas para puerto SVG a VML? de esa manera usted todavía podría tener un ‘HTML5’-tipo de solución
  • echa un vistazo a mi respuesta. exactamente lo que usted necesita

8 Kommentare

  1. 134

    Que curioso que haya hecho esta pregunta, yo hice hace poco para mi trabajo del sitio y yo estaba pensando en que debo escribir un tutorial… Aquí está cómo hacerlo con PHP/Imagick, que utiliza ImageMagick:

    $usmap = '/path/to/blank/us-map.svg';
    $im = new Imagick();
    $svg = file_get_contents($usmap);
    
    /*loop to color each state as needed, something like*/ 
    $idColorArray = array(
         "AL" => "339966"
        ,"AK" => "0099FF"
        ...
        ,"WI" => "FF4B00"
        ,"WY" => "A3609B"
    );
    
    foreach($idColorArray as $state => $color){
    //Where $color is a RRGGBB hex value
        $svg = preg_replace(
             '/id="'.$state.'" style="fill:#([0-9a-f]{6})/'
            , 'id="'.$state.'" style="fill:#'.$color
            , $svg
        );
    }
    
    $im->readImageBlob($svg);
    
    /*png settings*/
    $im->setImageFormat("png24");
    $im->resizeImage(720, 445, imagick::FILTER_LANCZOS, 1);  /*Optional, if you need to resize*/
    
    /*jpeg*/
    $im->setImageFormat("jpeg");
    $im->adaptiveResizeImage(720, 445); /*Optional, if you need to resize*/
    
    $im->writeImage('/path/to/colored/us-map.png');/*(or .jpg)*/
    $im->clear();
    $im->destroy();

    los pasos regex sustitución de color puede variar dependiendo de la ruta svg xml y cómo usted id & los valores de color son almacenados. Si usted no desea almacenar un archivo en el servidor, puede enviar la imagen como base 64 como

    <?php echo '<img src="data:image/jpg;base64,' . base64_encode($im) . '"  />';?>

    (antes de utilizar clear/destruir), pero ie tiene problemas con el PNG como base64 así que probablemente tenga que salida base64 como jpeg

    puede ver un ejemplo aquí hice para un antiguo jefe de ventas del territorio mapa:

    Inicio: https://upload.wikimedia.org/wikipedia/commons/1/1a/Blank_US_Map_(states_only).svg

    Convertir imagen SVG a PNG con PHP

    Acabado: Convertir imagen SVG a PNG con PHP

    Editar

    Desde que escribí el anterior, me he encontrado con 2 mejora de las técnicas:

    1) en lugar de una expresión regular bucle para cambiar el relleno en el estado , el uso de CSS para hacer que las reglas de estilo como

    <style type="text/css">
    #CA,#FL,HI{
        fill:blue;
    }
    #Al, #NY, #NM{
        fill:#cc6699;
    }
    /*etc..*/
    </style>

    y, a continuación, usted puede hacer un solo texto reemplazar a inyectar sus reglas css en el archivo svg antes de proceder con la imagick jpeg/png creación. Si los colores no cambian, asegúrese de que usted no tiene ninguna inline estilos de relleno en su camino etiquetas primordial de la css.

    2) Si usted no tiene que crear un archivo jpeg/archivo de imagen png (y no necesita soporte de los navegadores obsoletos), se puede manipular el svg directamente con jQuery. Usted no puede acceder a las rutas svg cuando la incrustación de la svg utilizando img o etiquetas object, por lo que tendrá que incluye directamente el xml svg en su página web html como:

    <div>
    <?php echo file_get_contents('/path/to/blank/us-map.svg');?>
    </div>

    a continuación, cambiar los colores es tan fácil como:

    <script type="text/javascript" src="/path/to/jquery.js"></script>
    <script type="text/javascript">
        $('#CA').css('fill', 'blue');
        $('#NY').css('fill', '#ff0000');
    </script>
    • Gracias por la muy exacta y útil tutorial sobre cómo hacer esto. Yo sin duda va a utilizar la solución como una copia de seguridad, pero estoy con ganas de probar y acaba de obtener el svg compatibilidad con todos los principales navegadores.
    • SVG no es compatible con internet explorer 8 o inferior, sin necesidad de que el usuario instale un svg viewer plugin – de SVG página de la Wikipedia: «Todos los principales navegadores web, de apoyo y de procesamiento SVG marcado directamente con la muy notable excepción de Microsoft Internet Explorer (IE)[3] Internet Explorer 9 beta soporta la básica SVG conjunto de características.[4] en la Actualidad, el soporte para los navegadores que se ejecutan bajo Android también es limitado.»
    • Sí, pero svgweb parece de hierro a cabo todas las incompatibilidades usando un poco de js y flash. Esa es la solución que me fui con.
    • Me gusta tu limpia y rápida solución. Personalmente a la hora de interactuar con archivos xml yo prefiero usar un analizador dom sentir más seguro que con regex. Sth como: $dom = new DOMDocument(); $dom->loadXML( $svg ); $dom->getElementsByTagName('image')->item(0)->setAttribute('id', $state); $svg = $dom->saveXML();
    • un analizador xml sería más seguro, aunque un poco más lento, con la solución de cualquier otra svg… en este caso el regex es seguro porque me aseguré de que cada estado de atributos que se han formateado exactamente como (id=»XX» style=»fill:#XXXXXX»).
    • ¿qué es $idColorArray? Lo que los colores que contiene? Cómo esta matriz parece?
    • Lo siento, se me olvidó incluir que. Las claves son el estado de los Identificadores y los valores son los valores de color hexadecimales. He añadido en un parcial ejemplo de $idColorArray a dejar esto en claro.
    • Clean & Solución Clara
    • bro necesito ayuda con la conversión de la imagen a formato svg vector que por favor me ayude , dispuestos a pagar por su tiempo, por favor agregame en skype : gauravkr.mishra90
    • Gracias por la oferta pero convertir una imagen en formato SVG vector es mucho más complicado que el proceso de convertir un SVG en una imagen. Lamentablemente no sé cómo hacerlo, así que yo no sería capaz de ayudar a
    • en mi caso tengo terribles imágenes de resolución porque yo era la mejora de las svg. sin embargo ajuste el tamaño de la imagen antes de cargar el svg resuelto este: stackoverflow.com/a/18521341/1698345

  2. 11

    Que mencionar que usted está haciendo esto porque IE no soporta SVG.

    La buena noticia es que el IE hace apoyo de gráficos vectoriales. Bueno, por lo que en la forma de un lenguaje denominado VML que solo IE apoya, más que SVG, pero está ahí, y se puede utilizar.

    Google Maps, entre otros, para detectar la capacidad del navegador para determinar si servir SVG o VML.

    Luego está el Rafael de la biblioteca, que es un Javascript navegador basado en la biblioteca de gráficos, que soporta SVG o VML, de nuevo, dependiendo del navegador.

    Otro en el que se puede ayudar a: SVGWeb.

    Todo lo cual significa que usted puede apoyar a su es decir que los usuarios sin tener que recurrir a gráficos de mapa de bits.

    Véase también la respuesta a esta pregunta, por ejemplo: Transformación XSL SVG para VML

    • +1 por mencionar a rafael, que es definitivamente una buena solución y que vale la pena investigar por su excelente ejecución de los navegadores gráficos vectoriales.
  3. 8

    Al convertir SVG a PNG transparente, no se olvide de poner esto ANTES de $imagick->readImageBlob():

    $imagick->setBackgroundColor(new ImagickPixel('transparent'));
  4. 6

    Este es v. fácil, han estado trabajando en esto durante las últimas semanas.

    Usted necesita el Batik SVG Toolkit. Descarga y colocar los archivos en el mismo directorio que el archivo SVG que quiere convertir a JPEG, también asegúrese de que descomprimirlo primero.

    Abrir el terminal y ejecutar este comando:

    java -jar batik-rasterizer.jar -m image/jpeg -q 0.8 NAME_OF_SVG_FILE.svg

    Que debe de salida JPEG del archivo SVG. Realmente fácil.
    Usted puede incluso acaba de colocar en un bucle y convertir las cargas de SVGs,

    import os
    
    svgs = ('test1.svg', 'test2.svg', 'etc.svg') 
    for svg in svgs:
        os.system('java -jar batik-rasterizer.jar -m image/jpeg -q 0.8 '+str(svg)+'.svg')
    • Esto es genial. Gracias por la sugerencia. Yo voy a utilizar en conjunción con perl para procesar por lotes las cargas de archivos SVG que he creado a partir de una plantilla.
  5. 2

    No sé de un autónomo PHP /Apache solución, ya que esto requeriría una librería PHP que puede leer y procesar las imágenes SVG. No estoy seguro de que una biblioteca existe – yo no conozco a ninguna.

    ImageMagick es capaz de rasterizar archivos SVG, ya sea a través de la línea de comandos o el PHP de unión, IMagick, pero parece que tiene una serie de peculiaridades y dependencias externas, como se muestra por ejemplo en este hilo del foro. Yo pienso que es la manera más prometedora para ir, es la primera cosa que me gustaría ver en si yo fuera usted.

  6. 1

    Este es un método para convertir una imagen svg a un gif utilizando el estándar de php GD herramientas

    1) poner la imagen en un elemento canvas en el navegador:

    <canvas id=myCanvas></canvas>
    
    <script>
    var Key='picturename'
    var canvas = document.getElementById('myCanvas');
    var context = canvas.getContext('2d');
    base_image = new Image();
    base_image.src = myimage.svg;
    base_image.onload = function(){
    
        //get the image info as base64 text string
    
        var dataURL = canvas.toDataURL();
        //Post the image (dataURL) to the server using jQuery post method
        $.post('ProcessPicture.php',{'TheKey':Key,'image': dataURL ,'h': canvas.height,'w':canvas.width,"stemme":stemme } ,function(data,status){ alert(data+' '+status) });
    }
    </script>    

    Y, a continuación, convertirlo en el servidor (ProcessPicture.php) (por defecto), png a gif y guardarlo. (usted podría haber ahorrado como png demasiado, a continuación, utilizar imagepng en lugar de la imagen gif):

    //receive the posted data in php
    $pic=$_POST['image'];
    $Key=$_POST['TheKey'];
    $height=$_POST['h'];
    $width=$_POST['w'];
    $dir='../gif/'
    $gifName=$dir.$Key.'.gif';
     $pngName=$dir.$Key.'.png';
    
    //split the generated base64 string before the comma. to remove the 'data:image/png;base64, header  created by and get the image data
    $data = explode(',', $pic);
    $base64img = base64_decode($data[1]);
    $dimg=imagecreatefromstring($base64img); 
    
    //in order to avoid copying a black figure into a (default) black background you must create a white background
    
    $im_out = ImageCreateTrueColor($width,$height);
    $bgfill = imagecolorallocate( $im_out, 255, 255, 255 );
    imagefill( $im_out, 0,0, $bgfill );
    
    //Copy the uploaded picture in on the white background
    ImageCopyResampled($im_out, $dimg ,0, 0, 0, 0, $width, $height,$width, $height);
    
    //Make the gif and png file 
    imagegif($im_out, $gifName);
    imagepng($im_out, $pngName);
    • Gran solución, ha funcionado bien para mí! Gracias
  7. -1
    $command = 'convert -density 300 ';
                            if(Input::Post('height')!='' && Input::Post('width')!=''){
                                $command.='-resize '.Input::Post('width').'x'.Input::Post('height').' ';
                            }
                            $command.=$svg.' '.$source;
                            exec($command);
                            @unlink($svg);

    o el uso de : potrace
    demo :Tool4dev.com

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea