用PHP将SVG图像转换为PNG

我正在开发一个Web项目,其中包含一个dynamic生成的美国地图,它根据一组数据着色不同的状态。

这个SVG文件给了我一个美国的空白地图,很容易改变每个国家的颜色。 难度在于IE浏览器不支持SVG,所以为了让我使用svg提供的方便的语法,我需要把它转换成JPG格式。

理想情况下,我只想用GD2库来做到这一点,但也可以使用ImageMagick。 我完全不知道如何做到这一点。

我们将考虑任何能够dynamic改变美国地图上的州的颜色的解决scheme。 关键是可以很容易地改变飞行中的颜色,并且它是跨浏览器的。 请仅使用PHP / Apache解决scheme。

这很有趣,你问了这个问题,最近我刚刚为我的工作网站做了这个,我想我应该写一个教程…以下是如何使用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(); 

正则expression式颜色replace的步骤可能会有所不同,具体取决于svgpathxml以及如何存储id和颜色值。 如果你不想在服务器上存储一个文件,你可以输出图像作为基础64像

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

(之前你使用清除/销毁),但即与PNG问题为base64,所以你可能不得不输出base64为JPEG

你可以在这里看到我为前雇主的销售领域地图做的一个例子:

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

完: 在这里输入图像描述

编辑

由于写了上述,我已经提出了2个改进的技术:

1)而不是正则expression式循环来改变填充状态,使用CSS来制作样式规则

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

然后你可以做一个单一的文本replace注入你的css规则到svg中,然后再进行imagick jpeg / png创build。 如果颜色不改变,请检查以确保您的path标记中没有任何内联填充样式覆盖css。

2)如果你不需要实际创build一个jpeg / png图像文件(不需要支持过时的浏览器),你可以直接用jQuery来操纵svg。 当使用img或object标签embeddedsvg时,您不能访问svgpath,所以您必须直接在您的网页html中包含svg xml,如:

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

那么改变颜色就像:

 <script type="text/javascript" src="/path/to/jquery.js"></script> <script type="text/javascript"> $('#CA').css('fill', 'blue'); $('#NY').css('fill', '#ff0000'); </script> 

另一个非常快速和准确的选项是无头浏览器PhantomJS(webkit)

http://phantomjs.org/

你提到你这样做是因为IE不支持SVG。

好消息是IE 确实支持vectorgraphics。 好的,所以它的forms是一种叫做VML的语言,只有IE支持,而不是SVG,但它在那里,你可以使用它。

谷歌地图等,将检测浏览器的function,以确定是否服务于SVG或VML。

然后是Raphael库 ,这是一个基于Javascript的browswergraphics库,它支持SVG或VML,这取决于浏览器。

另一个可能有助于: SVGWeb 。

所有这一切意味着您可以支持您的IE用户,而无需诉诸位图graphics。

另请参阅此问题的最佳答案,例如: XSL将SVG转换为VML

将SVG转换为透明PNG时,不要忘记把这个BEFORE $ imagick-> readImageBlob():

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

这很简单,在过去几周里一直在做这个工作。

你需要Batik SVG Toolkit 。 下载并将文件放在与要转换为JPEG的SVG相同的目录下 ,也请确保先解压缩。

打开terminal,运行这个命令:

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

这应该输出一个SVG文件的JPEG。 真的很容易。 你甚至可以把它放在一个循环中,并转换大量的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') 

您可以使用canvg js库将SVG转换为PNG,更多信息请访问http://paksula.users.cs.helsinki.fi/svg_open_2010/demo.xhtml与所有主stream浏览器兼容!;

我在我的项目中使用它,实际上将SVG转换成PNG(在PHP的帮助下保存文件当然)

我不知道独立的PHP / Apache解决scheme,因为这需要一个可以读取和呈现SVG图像的PHP库。 我不确定这样的图书馆是否存在 – 我不知道。

ImageMagick能够通过命令行或PHP绑定IMagick来栅格化SVG文件,但似乎有一些怪癖和外部依赖关系,如本论坛主题中所示 。 我认为这仍然是最有希望的方式,如果我是你,我会首先考虑的。

 $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); 

或使用:potrace演示: Tool4dev.com

您可以使用Raphaël-JavaScript库并轻松实现。 它也将在IE中工作。

Interesting Posts