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

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: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後,就可以自己合成各種圖片了,並且新增文字或者是其他圖形等,具體可以查閱官方文件。

本文參考文章:

  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.[實戰] 圖片轉素描圖

相關文章