问题描述
我正在开展一个网络项目,该项目涉及动态生成的美国地图,根据一组数据为不同的州着色.
这个 SVG 文件给了我一张很好的美国空白地图,而且很容易改变每个州的颜色.困难在于 IE 浏览器不支持 SVG,因此为了让我使用 svg 提供的方便语法,我需要将其转换为 JPG.
理想情况下,我只想使用 GD2 库来执行此操作,但也可以使用 ImageMagick.我完全不知道如何做到这一点.
任何允许我动态更改美国地图上各州颜色的解决方案都将被考虑.关键是很容易动态更改颜色,并且它是跨浏览器的.请仅使用 PHP/Apache 解决方案.
你问这个问题很有趣,我最近刚为我的工作网站做了这个,我想我应该写一个教程......这是如何做到的使用 PHP/Imagick,它使用 ImageMagick:
$usmap = '/path/to/blank/us-map.svg';$im = new Imagick();$svg = file_get_contents($usmap);/* 循环根据需要为每个状态着色,例如*/$idColorArray = 数组(AL"=>339966",AK"=>0099FF"...,WI"=>FF4B00",WY"=>A3609B");foreach($idColorArray as $state => $color){//其中 $color 是一个 RRGGBB 十六进制值$svg = preg_replace('/id="'.$state.'" style="fill:#([0-9a-f]{6})/', 'id="'.$state.'" style="fill:#'.$color, $svg);}$im->readImageBlob($svg);/*png 设置*/$im->setImageFormat("png24");$im->resizeImage(720, 445, imagick::FILTER_LANCZOS, 1);/*可选,如果你需要调整大小*//*JPEG*/$im->setImageFormat("jpeg");$im->adaptiveResizeImage(720, 445);/*可选,如果你需要调整大小*/$im->writeImage('/path/to/colored/us-map.png');/*(或.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_US_Map_(states_only).svg
完成:
编辑
自从写完上面的内容后,我想出了 2 个改进的技巧:
1) 而不是一个正则表达式循环来改变状态的填充,使用 CSS 来制作像
这样的样式规则#CA,#FL,HI{填充:蓝色;}#Al、#NY、#NM{填充:#cc6699;}/*等等..*/</风格>
然后你可以做一个单一的文本替换,在继续创建 imagick jpeg/png 之前将你的 css 规则注入到 svg 中.如果颜色没有改变,请检查以确保您的路径标签中没有任何内联填充样式覆盖了 css.
2) 如果您不需要实际创建 jpeg/png 图像文件(并且不需要支持过时的浏览器),您可以直接使用 jQuery 操作 svg.使用 img 或 object 标签嵌入 svg 时,您无法访问 svg 路径,因此您必须直接在网页 html 中包含 svg xml,例如:
<?php echo file_get_contents('/path/to/blank/us-map.svg');?>
然后改变颜色就像:
<script type="text/javascript" src="/path/to/jquery.js"></script><script type="text/javascript">$('#CA').css('填充', '蓝色');$('#NY').css('fill', '#ff0000');
I'm working on a web project that involves a dynamically generated map of the US coloring different states based on a set of data.
This SVG file gives me a good blank map of the US and is very easy to change the color of each state. The difficulty is that IE browsers don't support SVG so in order for me to use the handy syntax the svg offers, I'll need to convert it to a JPG.
Ideally, I'd like to do this with only the GD2 library but could also use ImageMagick. I have absolutely no clue how to do this.
Any solution that would allow me to dynamically change the colors of states on a map of the US will be considered. The key is that it is easy to change the colors on the fly and that it is cross browser. PHP/Apache solutions only, please.
That's funny you asked this, I just did this recently for my work's site and I was thinking I should write a tutorial... Here is how to do it with PHP/Imagick, which uses 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();
the steps regex color replacement may vary depending on the svg path xml and how you id & color values are stored. If you don't want to store a file on the server, you can output the image as base 64 like
<?php echo '<img src="data:image/jpg;base64,' . base64_encode($im) . '" />';?>
(before you use clear/destroy) but ie has issues with PNG as base64 so you'd probably have to output base64 as jpeg
you can see an example here I did for a former employer's sales territory map:
Start: https://upload.wikimedia.org/wikipedia/commons/1/1a/Blank_US_Map_(states_only).svg
Finish:
Edit
Since writing the above, I've come up with 2 improved techniques:
1) instead of a regex loop to change the fill on state , use CSS to make style rules like
<style type="text/css">
#CA,#FL,HI{
fill:blue;
}
#Al, #NY, #NM{
fill:#cc6699;
}
/*etc..*/
</style>
and then you can do a single text replace to inject your css rules into the svg before proceeding with the imagick jpeg/png creation. If the colors don't change, check to make sure you don't have any inline fill styles in your path tags overriding the css.
2) If you don't have to actually create a jpeg/png image file (and don't need to support outdated browsers), you can manipulate the svg directly with jQuery. You can't access the svg paths when embedding the svg using img or object tags, so you'll have to directly include the svg xml in your webpage html like:
<div>
<?php echo file_get_contents('/path/to/blank/us-map.svg');?>
</div>
then changing the colors is as easy as:
<script type="text/javascript" src="/path/to/jquery.js"></script>
<script type="text/javascript">
$('#CA').css('fill', 'blue');
$('#NY').css('fill', '#ff0000');
</script>
这篇关于使用 PHP 将 SVG 图像转换为 PNG的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!