Aliyun Linux 2上imageMagick的fonts配置问题
现象
公司阿里云服务器部署Rails程序时,发现Gem simple_captcha2生成的验证码图片,和以前的不太一样。图片中的数字会比正常情况下靠上很多, 影响用户体验。
正常情况下的图片:
有问题的图片:
原因
Aliyun Linux 2(也包含最新的CentOS 7)中升级了ImageMagick的版本到ImageMagick 6.9.10-68, 字体配置文件/etc/ImageMagick-6/type.xml中默认改用了urw-base35-fonts,而不是之前的ghostscript-fonts。
解决方法
安装并修改ImageMagick使用旧字体。
1 | # 安装urw-base35-fonts-legacy, fonts在/usr/share/X11/fonts/urw-fonts目录下 |
调查过程
查找生成图片的命令
首先翻simple_captcha2的源码, 看Gem是怎么生成图片的。后来定位到是lib/simple_captcha/image.rb文件中的generate_simple_captcha_image方法调用了ImageMagick的convert命令来生成图片。
命令形式类似如下:
1 | convert -background '#F5F7FA' -fill '#409EFF' -border 0 -bordercolor 'none' -size 80x30 -wave 1x89 -gravity Center -pointsize 22 -implode 0.2 label:1441 jpeg:- |
在Aliyun Linux 2上,简单试验了下,使用yum源安装的ImageMagick,使用如下官方Label的最简单的用法来生成图片。
1 | convert -background lightblue -fill blue -pointsize 72 label:Anthony label.gif |
可生成的图片的高度size只有1, 明显存在问题。
编译源码版本
看了下Aliyun Linux 2中通过yum安装的ImageMagick版本是ImageMagick 6.9.10-68 Q16 x86_64, 和经常使用的版本ImageMagick 6.7.8-9 2016-03-31不相同。
猜想可能是ImageMagick版本变化导致了图片的位置不对。
尝试使用源码来进行安装6.7.8版本, 在帖子Old releases source code中找到了官方的源码目录,但已经没有6.7.8-9的源码提供了,因此下载了6.7.8-10的源码, 按照官网Install from Unix Source的说明进行编译安装。
1 | wget 'https://www.imagemagick.org/download/releases/ImageMagick-6.7.8-10.tar.xz' |
尝试使用该版本的convert生成图片。
1 | $ /usr/local/bin/convert --version |
会有找不到font的报错, 但是能生成图片,并且图片中的数字没有出现上移情况。
寻找fonts问题
根据font的报错信息,调查了ImageMagick的fonts配置。
yum安装的ImageMagick的配置文件目录为/etc/ImageMagick-6/, 自编译的ImageMagick的配置文件目录为/usr/local/etc/ImageMagick/。
尝试着让自编译版本的ImageMagick使用yum安装的字体配置type-urw-base35.xml。
我把yum安装的ImageMagick的字体配置type-urw-base35.xml拷贝到了自编译的配置目录下/usr/local/etc/ImageMagick/, 再修改type.xml为使用type-urw-base35.xml
1 | cp /etc/ImageMagick-6/type-urw-base35.xml /usr/local/etc/ImageMagick/ |
然后尝试执行自编译的6.7.8_10版本的convert来生成验证码图片。
1 | /usr/local/bin/convert -background '#F5F7FA' -fill '#409EFF' -border 0 -bordercolor 'none' -size 80x30 -wave 1x89 -gravity Center -pointsize 22 -implode 0.2 label:1441 jpeg:- > fonts_compiled_with_urw-base35.jpeg |
本以为这事就可以这么搞定了。结果却发现,命令的错误信息是没了,但是生成的图片上的数字居然又是偏上的。
这说明有问题的可能不是ImageMagick命令,而是字体问题。
验证fonts问题
为了验证是不是font问题,我先是尝试修改yum的ImageMagick使用自带的type-ghostscript.xml配置文件。
1 | sed -i.bak 's,type-urw-base35.xml,type-ghostscript.xml,g' /etc/ImageMagick-6/type.xml |
可运行时就直接报错了。
1 | $ /usr/bin/convert -background '#F5F7FA' -fill '#409EFF' -border 0 -bordercolor 'none' -size 80x30 -wave 1x89 -gravity Center -pointsize 22 -implode 0.2 label:1441 jpeg:- > yum_with_type-ghostscript.jpeg |
失败后,再尝试让yum的ImageMagick使用编译版本的type-ghostscript.xml配置文件,
1 | cp /usr/local/etc/ImageMagick/type-ghostscript.xml /etc/ImageMagick-6/ |
可运行后还是报错。
1 | $ /usr/bin/convert -background '#F5F7FA' -fill '#409EFF' -border 0 -bordercolor 'none' -size 80x30 -wave 1x89 -gravity Center -pointsize 22 -implode 0.2 label:1441 jpeg:- > yum_with_compiled_type-ghostscript.jpeg |
一通操作后,得了一堆的错,不得不来挖一下ImageMagick是怎么使用系统的fonts了。
深挖fonts问题
在RHEL 7.7之后,使用了urw-base35-fonts代替了原先默认的urw-fonts, 期间导致了一些软件出现了些问题。
- CentOS 7.7.1908 ImageMagick montage does not work with urw-base35-fonts replacing urw-fonts
- CentOS Bug Tracker
- Bug 1756521 - urw-base35-fonts-20170801-10.el7.noarch.rpm removes fonts in /usr/share/fonts/default/Type1 and breaks htmldoc symlinks in /usr/share/htmldoc/fonts
在7.7之后,默认的yum源中有三组相关的font
- urw-fonts
- urw-base35-fonts
- urw-base35-fonts-legacy
其中urw-fonts被urw-base35-fonts废弃替换了。但可以通过手动下载手动安装的方式来进行安装。
1 | rpm -ivh --nodeps urw-fonts-2.4-16.1.al7.noarch.rpm |
安装后,三个的目录分别为:
- /usr/share/fonts/default/Type1
- /usr/share/fonts/urw-base35
- /usr/share/X11/fonts/urw-fonts
yum源中的ImageMagick后续应该是解决了使用urw-base35-fonts的问题, 因为字体配置文件/etc/ImageMagick-6/type.xml中默认是使用了type-urw-base35.xml。但不知为啥,ImageMagick使用字体urw-base35-fonts,用label生成图片的时候,存在着文字上移的问题。
试验下来,最终解决方案如下:
- 使用
yum install ImageMagick安装ImageMagick - 再安装
urw-base35-fonts-legacy字体, - 最后修改ImageMagick的配置文件来使用legacy的字体,最终解决了该问题。
1 | # 安装urw-base35-fonts-legacy, fonts在/usr/share/X11/fonts/urw-fonts目录下 |
额外延伸
ImageMagick的font配置文件
ImageMagick使用配置目录下的type.xml来控制使用哪个fonts
- yum原生安装的ImageMagick,配置文件目录:
/etc/ImageMagick-6/type.xml或/etc/ImageMagick/type.xml - 源码编译的ImageMagick, 默认配置文件目录:
/usr/local/etc/ImageMagick/type.xml
可使用如下命令列出配置中支持的fonts。
1 | convert -list type # for IM older than v6.3.5-7 |
ImageMagick使用urw-fonts字体
下载yum中的rpm包
1 | # yum install yum-utils |
使用--nodeps安装rpm包
1 | # rpm -ivh --nodeps urw-fonts-2.4-16.1.al7.noarch.rpm |
删除rpm包命令: rpm -e urw-fonts-2.4-16.1.al7.noarch
配置ImageMagick使用urw-fonts字体
1 | 修改 /etc/ImageMagick-6/type.xml |
Reference
- With ImageMagick, how can you see all available fonts?
- Make ImageMagick recognize a font
- CentOS 7.7.1908 ImageMagick montage does not work with urw-base35-fonts replacing urw-fonts
- CentOS Bug Tracker
- Bug 1756521 - urw-base35-fonts-20170801-10.el7.noarch.rpm removes fonts in /usr/share/fonts/default/Type1 and breaks htmldoc symlinks in /usr/share/htmldoc/fonts
- Bug 1743658 - [config/type-ghostscript.xml.in] using outdated hardcoded paths for (URW)++ fonts
- Bug 1500104 - urw-base35-fonts only partially provides urw-fonts and should at least obsolete ghostscript-fonts, too.
- [CentOS 7.7 > ImageMagick > フォントがない > unable to read font `/usr/share/fonts/default/Type1/n019003l.pfb’ | link:yumとrpmでのパッケージ情報表示 | yum whatprovides /usr/share/fonts/default](https://qiita.com/7of9/items/7c8e34e29d0dc338f5ea)
- Difference between caption, draw, annotate, label while adding text to ImageMagick
- ImageMagick用法
- Issue with stroke and label: text - IM 7.0.7-39 and 6.9.9-50