本文大约 1933 字,阅读大约需要 6 分钟
最近刚刚更换了公众号名字,然后自然就需要更换下文章末尾的二维码关注图,但是之前是通过 windows 自带的画图软件做的,但是之前弄的时候其实还是比较麻烦的,所以我就想作为一名程序猿,当然要努力用代码解决这个问题。
而且最近发现了一个新的图像处理方面的库–Wand,它是 ImageMagick 库的 Python 接口。于是,我就打算用这个库来实现简单的制作一个二维码关注图,主要是完成以下几个工作:
Wand 是基于 ctypes 库的适用于 Python 的 ImageMagick 的封装库。
相比其他对 ImageMagick 的封装库,Wand 有以下几个优势:
在 ubuntu下,可以直接按照下列命令安装:
$ apt-get install libmagickwand-dev
$ pip install Wand
对 Python 版本要求:
MagickWand library
主要还是参照第一篇文章来安装,并且主要是在 Windows 下安装,其中下载 ImageMagick 的时候,在下载地址中需要选择 6.9版本的 dll 的 exe 执行文件安装,而不能选择最新版本的 7.0+,否则在 Python 中调用的时候,会出现问题ImportError: MagickWand shared library not found.
,原因根据Python doesn’t find MagickWand Libraries (despite correct location?)中的说法是
A few sources said that Image Magick 7.x is not compatible with magick Wand so make sure you’re using 6.x. Additionally, “static” suffix versions do not work. The one that finally worked for me was “ImageMagick-6.9.8-10-Q8-x64-dll.exe”
也就是说 Image Magick 7.x 版本和 Wand 并不适配,所以只能采用 6+ 版本的。
安装完成后,这里首先需要准备一张或者几张要合成的图片,比如作为背景的图片和前景图片,这里我是先给定大小来生成背景图片,而前景图片自然是我的公众号二维码图片了:
首先是需要导入以下这些包:
from wand.image import Image
from wand.drawing import Drawing
from wand.color import Color
from wand.display import display
生成背景图片的代码如下所示:
# 画一个纯白背景,并保存
def draw_bg(self, width, height, filename=None, color='white'):
img = Image(width=width, height=height, background=Color(color))
if filename is not None:
img.save(filename=filename)
return img
这里就是根据传入的宽和高width,height
,以及背景颜色color
,生成指定大小和颜色的背景图片。
接着就是合成图片的函数代码:
# 合成图片
def composite_with_image(self, img_back, img, left, top, save_name=None, is_display=False):
draw = Drawing()
draw.composite(operator='atop',
left=left, top=top,
width=img.width,
height=img.height,
image=img)
draw(img_back)
if is_display:
display(img_back)
if save_name is not None:
img_back.save(filename=save_name)
return img_back
# 读取图片
def read_image(self, image_name):
img = Image(filename=image_name)
print('width=', img.width)
print('height=', img.height)
print('size=', img.size)
return img, img.width, img.height
首先是用read_image()
函数读取待合成的图片,然后利用composite_with_image
函数来合成输入的两张图片,其中img_back
表示背景图片,而img
就是前景图片,left, top
分别是前景图片在背景图片的左上角坐标位置。
这一步得到的结果如下所示,这里我设置的背景图片大小为:
image_name = 'qrcode.jpg'
qrcode_img, width, height = read_image(images_name)
bg_width = int(width * 2.5)
bg_height = int(height * 1.1)
最后一步就是添加文字了,前面两步其实都非常简单,直接调用接口即可,但是添加文字的时候,却出现问题了。是什么问题呢?
首先先给出wand
添加文字的代码:
def draw_text(self, image, x, y, text, font_size=15, font_style='normal', text_alignment='left',text_color='Black', filename=None, is_display=False):
draw = Drawing()
draw.fill_color = Color(text_color)
draw.font_size = font_size
draw.font_style = font_style
draw.text_alignment = text_alignment
draw.text(x, y, text)
draw(image)
if is_display:
display(image)
if filename is not None:
image.save(filename=filename)
return image
刚刚说的问题,其实也是 Python 很常见的问题,就是如果使用到中文的字符串的问题,本来我认为也是编码问题,但是我发现设置一个只包含英文字符串,和包含有中文字符串的结果是这样的:
代码如下所示:
text1 = 'Hello world'
text2 = 'wechat:机器学习与计算机视觉'
x = int(width * 1.5) + 50
margin = 60
y2 = int(bg_height // 2)
y1 = y2 - margin
x1 = x2 = x + 20
result1 = draw_text(composite_images, x1, y1, text1, font_size=20, text_color='Gray', text_alignment='center', filename='qrcode_composition.jpg', is_display=False)
result2 = draw_text(result1, x2, y2, text2, font_size=30, text_color='Black',
text_alignment='center',filename='qrcode_composition.jpg',
is_display=False)
所以这应该不是编码问题,通过谷歌搜索后,发现应该是wand
默认不支持中文字符的原因,接着在看到参考文章4后,我发现可以通过wand.drawing.Drawing.font()
接口导入支持中文的字体来解决这个问题,而这些字体在哪里可以找到呢,其实在c:\windows\fonts\
目录下面就可以找到了,宋体、微软雅黑的字体,只要指定字体路径即可,因此更新后的代码如下:
FONT_DICT = {'宋体': 'songti.ttc',
'微软雅黑1': 'msyh.ttc',
'微软雅黑2': 'msyhbd.ttc',
'微软雅黑3': 'msyhl.ttc'}
def draw_text(self, image, x, y, text, font_size=15, font_style='normal',font=None, text_alignment='left',text_color='Black', filename=None, is_display=False):
draw = Drawing()
if font is not None:
draw.font = font
draw.fill_color = Color(text_color)
draw.font_size = font_size
draw.font_style = font_style
draw.text_alignment = text_alignment
draw.text(x, y, text)
draw(image)
if is_display:
display(image)
if filename is not None:
image.save(filename=filename)
return image
最终合成的结果如下:
完整代码可以到我的Github上查看–image_composition.py
这次的实战练习其实非常简单,唯一比较有困难的就是解决如何添加中文的文字了,但是还是非常实用的,熟练学会这个Wand
后,就可以自己合成各种图片了,并且添加文字或者是其他图形等,具体可以查阅官方文档。
本文参考文章:
- Wand–Installtion
- imagemagick home
- Wand Documentation
- 用ImageMagick在图片中写中文的问题及解决
- python-wand-change-text-style-with-draw-text
以上就是本文的主要内容和总结,欢迎留言给出你对本文的建议和看法。
同时也欢迎关注我的微信公众号–机器学习与计算机视觉或者扫描下方的二维码,和我分享你的建议和看法,指正文章中可能存在的错误,大家一起交流,学习和进步!
推荐阅读
1.机器学习入门系列(1)–机器学习概览(上)
2.机器学习入门系列(2)–机器学习概览(下)
3.[实战] 图片转素描图