使用 ImageMagick
ImageMagick 是老牌的图片解决方案了,这次在 node.js 项目里本想用它的一个演进项目 GraphicsMagick,只可惜,在同样使用 gm 这个 npm 的情况下,GraphicsMagick 对中文的支持太不好了,于是在折腾一番后,还是选择放弃尝试新的事物,转为继续使用各方面技术支持更广泛的老大哥 ImageMagick。
我的需求是需要将 SVG 转为 Raster Graphics (位图),例如将如下 SVG 转为 JPG:
http://www.w3.org/TR/2009/WD-SVGCompositing-20090430/examples/over.svg
结果转换成 JPG 后,图片变成:
内容细节严重丢失,内嵌图片不见了。
经过各种参数调整,可问题依然。此时,查看官方文档发现一些问题:
ImageMagick 对 SVG 支持三种格式:MSVG, SVG, SVGZ。MSVG 为 ImageMagick 的内建库;SVG 和 SVGZ 则依赖其他一些库,比如,官方推荐的 RSVG。
于是用命令查看对 SVG 的支持情况:1
convert -list format | grep SVG
返回1
2
3MSVG SVG rw+ ImageMagick's own SVG internal renderer
SVG SVG rw+ Scalable Vector Graphics (XML 2.7.8)
SVGZ SVG rw+ Compressed Scalable Vector Graphics (XML 2.7.8)
XML?!坑爹啊!果然不是 RSVG 库,还不是得很奇葩……
好吧!装库!
一堆问题
先安装 librsvg 库,在 Mac 下我目前采用 brew 解决包管理,所以:1
brew install librsvg
结果报错,如下:1
2
3
4
5
6
7
8
9
10
11
12
13librsvg: Unsatisfied dependency: XQuartz
Homebrew does not package XQuartz. Installers may be found at:
https://xquartz.macosforge.org
cairo: Unsatisfied dependency: XQuartz
Homebrew does not package XQuartz. Installers may be found at:
https://xquartz.macosforge.org
pango: Unsatisfied dependency: XQuartz
Homebrew does not package XQuartz. Installers may be found at:
https://xquartz.macosforge.org
gtk+: Unsatisfied dependency: XQuartz 2.3.6
Homebrew does not package XQuartz. Installers may be found at:
https://xquartz.macosforge.org
Error: An unsatisfied requirement failed this build.
这才发现,原来 Mac 10.8 上没有 X11,好吧,安装一个,Apple 官方推荐的下载地址:
是 dmg 文件,如何安装就是不用说了。XQuartz 安装完之后,再次运行安装 librsvg 的命令就势如破竹了。
librsvg 安装好之后需要重新安装 ImageMagick,网上找到 —use-rsvg 这个参数,但结果是又一次坑爹了。一阵安装编译等待之后,依旧显示 (XML 2.7.8)!!!什么情况呢?重新进入无尽的搜索,最后是从 brew 源代码里找到当前 brew 版本中的正确参数 —with-librsvg。源码见:
https://github.com/mxcl/homebrew/blob/master/Library/Formula/imagemagick.rb
结果执行如下命令就成功了…1
brew reinstall imagemagick --with-librsvg --with-webp
检验一下:1
2
3
4convert -list format | grep SVG
MSVG SVG rw+ ImageMagick's own SVG internal renderer
SVG SVG rw+ Scalable Vector Graphics (RSVG 2.36.3)
SVGZ SVG rw+ Compressed Scalable Vector Graphics (RSVG 2.36.3)
另外,如果此时还有问题,识别不到 RSVG 的话,请添加以下环境变量:
1 export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/opt/X11/lib/pkgconfig
而,如果是使用 port 的,命令如下:1
port install imagemagick +rsvg
按理到这里为止,ImageMagick 已经可以正常通过 librsvg 来渲染 SVG 格式的图片了,但是在我的 Mac 环境里始终存在丢失 xlink 进来的外链 image 的问题。于是又进入了茫然……
不要妄自菲薄
为了解决 node.js 下使用 ImageMagick 来处理图片的问题,前后折腾了几个小时,当所有已知问题都解决的时候一切回到原点。很不甘,是哪儿弄错了?于是又折腾了几个小时……
由于使用场景和使用的细节已然是少数需求了,国内相关文字几乎为零,英文站点上的内容也极少。stackoverflow 上尽是提问的,回答了了,更多的是根本没有回答。
突然,因为连续几篇文字提到了 ImageMagick 的不同版本对于类似的 convert 时出现的 bug,于是我怀疑是我环境里 ImageMagick 版本的问题。立刻在服务器环境中进行了测试(ImageMagick 6.5.4-7 with RSVG 2.26.0 on CentOS)果然,一切正常了!OMG!
出错的是 ImageMagick 6.8.6-3 with RSVG 2.36.3 版本,貌似是 RSVG 的错误,具体哪里出错暂时无力再去验证。具体错误表现是:
- xlink:href=”abc.png” 同目录丢失
- xlink:href=”./abc.png” 相对路径丢失
- xlink:href=”/path/to/abc.png” 绝对路径丢失
- xlink:href=”data:image/png;base64,…=” 内嵌 Base64 格式正常
最后得到正确的图像输出:
此时,我想说,虽然常提“不要妄自菲薄”,但是做到还是挺难的。质疑问题需要的是锲而不舍的精神和精湛的技艺,我辈还不具备两者,还没勇气去怀疑知名软件库,真是还需努力!