[實戰]製作簡單的公眾號二維碼關注圖

spearhead_cai發表於2019-03-04

本文大約 1933 字,閱讀大約需要 6 分鐘

最近剛剛更換了公眾號名字,然後自然就需要更換下文章末尾的二維碼關注圖,但是之前是通過 windows 自帶的畫圖軟體做的,但是之前弄的時候其實還是比較麻煩的,所以我就想作為一名程式猿,當然要努力用程式碼解決這個問題。

而且最近發現了一個新的影象處理方面的庫--Wand,它是 ImageMagick 庫的 Python 介面。於是,我就打算用這個庫來實現簡單的製作一個二維碼關注圖,主要是完成以下幾個工作:

  1. 製作一個白色的背景圖;
  2. 將背景圖和公眾號二維碼圖合成;
  3. 新增文字得到最終的合成圖

簡介

Wand 是基於 ctypes 庫的適用於 Python 的 ImageMagick 的封裝庫。

相比其他對 ImageMagick 的封裝庫,Wand 有以下幾個優勢:

  1. 符合 Python 習慣和現代化的介面
  2. 有好的文件
  3. 通過 ctypes 進行封裝
  4. 可以採用 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:\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

小結

這次的實戰練習其實非常簡單,唯一比較有困難的就是解決如何新增中文的文字了,但是還是非常實用的,熟練學會這個Wand後,就可以自己合成各種圖片了,並且新增文字或者是其他圖形等,具體可以查閱官方文件。

本文參考文章:

  1. Wand--Installtion
  2. imagemagick home
  3. Wand Documentation
  4. 用ImageMagick在圖片中寫中文的問題及解決
  5. python-wand-change-text-style-with-draw-text

以上就是本文的主要內容和總結,歡迎留言給出你對本文的建議和看法。

同時也歡迎關注我的微信公眾號--機器學習與計算機視覺或者掃描下方的二維碼,和我分享你的建議和看法,指正文章中可能存在的錯誤,大家一起交流,學習和進步!

[實戰]製作簡單的公眾號二維碼關注圖

推薦閱讀

1.機器學習入門系列(1)--機器學習概覽(上)

2.機器學習入門系列(2)--機器學習概覽(下)

3.[實戰] 圖片轉素描圖

相關文章