extension - imagick php examples
Convierta imagen SVG a PNG con PHP (10)
Al convertir SVG a PNG transparente, no olvide poner esto ANTES de $ imagick-> readImageBlob ():
$imagick->setBackgroundColor(new ImagickPixel(''transparent''));
Estoy trabajando en un proyecto web que involucra un mapa de Estados Unidos generado dinámicamente para colorear diferentes estados según 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 los navegadores IE no son compatibles con SVG, así que para poder usar la útil sintaxis que svg ofrece, tendré que convertirlo a JPG.
Idealmente, me gustaría hacer esto solo con la biblioteca GD2, pero también podría usar ImageMagick. No tengo ni idea de cómo hacer esto.
Se considerará cualquier solución que me permita cambiar dinámicamente los colores de los estados en un mapa de los EE. UU. La clave es que es fácil cambiar los colores sobre la marcha y que es un navegador cruzado. Solo soluciones PHP / Apache, por favor.
Es gracioso que preguntes esto, acabo de hacer esto recientemente para el sitio de mi trabajo y estaba pensando que debería escribir un tutorial ... Aquí está cómo hacerlo con PHP / Imagick, que usa 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 del reemplazo del color de la expresión regular pueden variar dependiendo de la ruta de acceso svg xml y cómo se almacenan los valores de ID y color. Si no desea almacenar un archivo en el servidor, puede generar la imagen como base 64 como
<?php echo ''<img src="data:image/jpg;base64,'' . base64_encode($im) . ''" />'';?>
(antes de usar clear / destroy) pero tiene problemas con PNG como base64, entonces probablemente tendrías que sacar base64 como jpeg
Puede ver un ejemplo aquí que hice para el mapa del territorio de ventas de un antiguo empleador:
Inicio: https://upload.wikimedia.org/wikipedia/commons/1/1a/Blank_US_Map_(states_only).svg
Terminar:
Editar
Desde que escribí lo anterior, presenté dos técnicas mejoradas:
1) en lugar de un ciclo regex para cambiar el estado de relleno, use CSS para hacer reglas de estilo como
<style type="text/css">
#CA,#FL,HI{
fill:blue;
}
#Al, #NY, #NM{
fill:#cc6699;
}
/*etc..*/
</style>
y luego puedes hacer un único reemplazo de texto para inyectar tus reglas css en svg antes de proceder con la creación de imagick jpeg / png. Si los colores no cambian, verifique que no haya ningún estilo de relleno en línea en las etiquetas de su ruta que sobrescriban el CSS.
2) Si no tiene que crear realmente un archivo de imagen jpeg / png (y no necesita admitir navegadores desactualizados), puede manipular el svg directamente con jQuery. No puede acceder a las rutas svg al incrustar el svg usando etiquetas img o object, por lo que deberá incluir directamente el svg xml en su página web html como:
<div>
<?php echo file_get_contents(''/path/to/blank/us-map.svg'');?>
</div>
luego, 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>
Este es un método para convertir una imagen svg en un gif usando herramientas php GD estándar
1) Pones 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 luego conviértalo en el servidor (ProcessPicture.php) desde (predeterminado) png a gif y guárdalo. (También podría haber guardado como png y luego usar imagepng en lugar de 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);
Esto es v. Fácil, he estado trabajando en esto durante las últimas semanas.
Necesitas el Batik SVG Toolkit . Descargue y coloque los archivos en el mismo directorio que el SVG que desea convertir a JPEG , también asegúrese de descomprimirlo primero.
Abra la terminal y ejecute este comando:
java -jar batik-rasterizer.jar -m image/jpeg -q 0.8 NAME_OF_SVG_FILE.svg
Eso debería generar un archivo JPEG del archivo SVG. Realmente fácil. Incluso puede colocarlo en un bucle y convertir cargas de SVG,
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'')
Menciona que está haciendo esto porque IE no es compatible con SVG.
La buena noticia es que IE admite gráficos vectoriales. Está bien, así que está en la forma de un lenguaje llamado VML que solo IE soporta, en lugar de SVG, pero está ahí, y puedes usarlo.
Google Maps, entre otros, detectará las capacidades del navegador para determinar si sirve SVG o VML.
Luego está la biblioteca de Raphael , que es una biblioteca de gráficos basada en browswer de Javascript, que admite SVG o VML, de nuevo dependiendo del navegador.
Otro que puede ayudar: SVGWeb .
Todo lo cual significa que puede apoyar a sus usuarios de IE sin tener que recurrir a gráficos de mapa de bits.
Consulte también la respuesta principal a esta pregunta, por ejemplo: XSL Transform SVG to VML
No sé de una solución PHP / Apache independiente, ya que esto requeriría una biblioteca PHP que pueda leer y representar imágenes SVG. No estoy seguro de que exista tal biblioteca, no sé ninguna.
ImageMagick es capaz de rasterizar archivos SVG, ya sea a través de la línea de comandos o el enlace PHP, IMagick , pero parece tener una serie de caprichos y dependencias externas, como se muestra, por ejemplo, en este hilo del foro . Creo que todavía es la forma más prometedora de ir, es lo primero que vería si fuera tú.
Otra opción muy rápida y precisa es el navegador sin cabeza PhantomJS (webkit)
Puede usar Raphaël-JavaScript Library y lograrlo fácilmente. Funcionará en IE también.
puede usar la biblioteca canvg js para convertir el SVG en PNG, más información aquí http://paksula.users.cs.helsinki.fi/svg_open_2010/demo.xhtml compatible con todos los navegadores más importantes!
Lo estoy usando en mi proyecto y realmente convierte el SVG en PNG (con la ayuda de PHP para guardar el archivo por supuesto)
$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 utilizando: demo de Tool4dev.com : Tool4dev.com