本文大約 1933 字,閱讀大約需要 6 分鐘
最近剛剛更換了公眾號名字,然後自然就需要更換下文章末尾的二維碼關注圖,但是之前是通過 windows 自帶的畫圖軟體做的,但是之前弄的時候其實還是比較麻煩的,所以我就想作為一名程式猿,當然要努力用程式碼解決這個問題。
而且最近發現了一個新的影像處理方面的庫–Wand,它是 ImageMagick 庫的 Python 介面。於是,我就打算用這個庫來實現簡單的製作一個二維碼關注圖,主要是完成以下幾個工作:
- 製作一個白色的背景圖;
- 將背景圖和公眾號二維碼圖合成;
- 新增文字得到最終的合成圖
簡介
Wand 是基於 ctypes 庫的適用於 Python 的 ImageMagick 的封裝庫。
相比其他對 ImageMagick 的封裝庫,Wand 有以下幾個優勢:
- 符合 Python 習慣和現代化的介面
- 有好的文件
- 通過 ctypes 進行封裝
- 可以採用 pip 安裝
安裝教程
在 ubuntu下,可以直接按照下列命令安裝:
$ apt-get install libmagickwand-dev
$ pip install Wand
複製程式碼
安裝要求
對 Python 版本要求:
- Python 2.6+
- CPython 2.6+
- CPython 3.2+ or higher
- PyPy 1.5+ or higher
MagickWand library
- Debian/Ubuntu 系統:採用 apt-get 安裝 libmagickwand-dev
- Mac 系統:用 MacPorts/Homebrew 安裝 imagemagick
- CentOS 系統: 使用 yum 安裝 ImageMagick-devel
Windows 注意事項
主要還是參照第一篇文章來安裝,並且主要是在 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
複製程式碼
1. 生成背景圖片
生成背景圖片的程式碼如下所示:
# 畫一個純白背景,並儲存
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
,生成指定大小和顏色的背景圖片。
2. 將背景圖和公眾號二維碼圖合成
接著就是合成圖片的函式程式碼:
# 合成圖片
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)
複製程式碼
3. 新增文字
最後一步就是新增文字了,前面兩步其實都非常簡單,直接呼叫介面即可,但是新增文字的時候,卻出現問題了。是什麼問題呢?
首先先給出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:windowsfonts
目錄下面就可以找到了,宋體、微軟雅黑的字型,只要指定字型路徑即可,因此更新後的程式碼如下:
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
小結
這次的實戰練習其實非常簡單,唯一比較有困難的就是解決如何新增中文的文字了,但是還是非常實用的,熟練學會這個Wand
後,就可以自己合成各種圖片了,並且新增文字或者是其他圖形等,具體可以查閱官方文件。
本文參考文章:
以上就是本文的主要內容和總結,歡迎留言給出你對本文的建議和看法。
同時也歡迎關注我的微信公眾號–機器學習與計算機視覺或者掃描下方的二維碼,和我分享你的建議和看法,指正文章中可能存在的錯誤,大家一起交流,學習和進步!
推薦閱讀