使用 PHP 将 SVG 图像转换为 PNG

新手上路,请多包涵

我正在开发一个网络项目,该项目涉及根据一组数据为不同州着色的美国动态生成地图。

这个 SVG 文件给了我一张很好的美国空白地图,并且很容易改变每个州的颜色。困难在于 IE 浏览器不支持 SVG,所以为了让我使用 svg 提供的便捷语法,我需要将其转换为 JPG。

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

将考虑任何允许我动态更改美国地图上各州颜色的解决方案。关键是它很容易动态更改颜色并且它是跨浏览器的。请仅使用 PHP/Apache 解决方案。

原文由 Mike B 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

你问这个很有趣,我最近刚刚为我的工作网站做了这个,我想我应该写一个教程……这是使用 ImageMagick 的 PHP/Imagick 的方法:

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

正则表达式颜色替换的步骤可能会有所不同,具体取决于 svg 路径 xml 以及您的 id 和颜色值的存储方式。如果您不想在服务器上存储文件,则可以将图像输出为 base 64,如

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

(在你使用 clear/destroy 之前)但是 ie 有问题将 PNG 作为 base64,所以你可能不得不将 base64 输出为 jpeg

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

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

结束:在此处输入图像描述

编辑

自从写了上面的内容以来,我提出了 2 个改进的技术:

1)而不是正则表达式循环来更改状态的填充,使用 CSS 来制作样式规则,如

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

然后您可以进行单个文本替换以将您的 css 规则注入到 svg 中,然后再继续进行 imagick jpeg/png 创建。如果颜色没有改变,请检查以确保您的路径标签中没有任何内联填充样式覆盖 css。

  1. 如果您不必实际创建 jpeg/png 图像文件(并且不需要支持过时的浏览器),您可以直接使用 jQuery 操作 svg。使用 img 或 object 标签嵌入 svg 时,您无法访问 svg 路径,因此您必须直接在网页 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>

原文由 WebChemist 发布,翻译遵循 CC BY-SA 4.0 许可协议

我也想分享我的答案,它可能会对某人有所帮助。

当您的 svg 不包含填充样式且默认为黑色并且您希望将其转换为 png 并将颜色添加到结果 png 时,这更适用于简单的情况。

 function convertSvgToPng($svgPath, $fillColor, $outPath)
{
    $im = new Imagick();
    $svg = file_get_contents($svgPath);

    // !!! THIS is the trick part - just appending to all <path fill color
    $svg = str_replace('<path ', '<path style="fill:'.$fillColor.'" ', $svg);

    $im->readImageBlob($svg);
    $im->setImageFormat("png24");

    $im->writeImage($outPath);
    $im->clear();
    $im->destroy();
}

原文由 Armen 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题