你问这个问题很有趣,我最近刚刚为我的工作网站做了这个,我想我应该写一个教程...以下是如何使用 PHP/Imagick(它使用 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();
正则表达式颜色替换的步骤可能会有所不同,具体取决于 svg 路径 xml 以及 id 和颜色值的存储方式。如果你不想在服务器上存储文件,你可以将图像输出为base 64,例如
<?php echo '<img src="data:image/jpg;base64,' . base64_encode($im) . '" />';?>
(在使用clear/destroy之前)但是IE将PNG作为base64存在问题,因此您可能必须将base64输出为jpeg
您可以在这里看到我为前雇主的销售区域地图所做的示例:
Start: https://upload.wikimedia.org/wikipedia/commons/1/1a/Blank_US_Map_(states_only).svg https://upload.wikimedia.org/wikipedia/commons/1/1a/Blank_US_Map_(states_only).svg
Finish:
Edit
自从写完上面的内容后,我想出了两种改进的技术:
1) 使用 CSS 制定样式规则,而不是使用正则表达式循环来更改填充状态
<style type="text/css">
#CA,#FL,HI{
fill:blue;
}
#Al, #NY, #NM{
fill:#cc6699;
}
/*etc..*/
</style>
然后,您可以执行单个文本替换,将 css 规则注入到 svg 中,然后再继续创建 imagick jpeg/png。如果颜色没有改变,请检查以确保路径标记中没有任何覆盖 css 的内联填充样式。
2)如果您不需要实际创建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>