用Python寫一份獨特的元宵節祝福

今天是正月十五,首先祝你們元宵節快樂!node

之前加過我我的微信號的朋友,能夠在朋友圈看到我今天發的元宵節祝福圖片:python

這個祝福文字乍一看其貌不揚,不過點開大圖有驚喜:是拿本身微信好友的頭像拼成的編程

這是經過 python 編程生成的。怎麼樣,要不要來試下呢?canvas

涉及的原理並不複雜,接下來咱們一步步來講明。微信

首先是點陣字的概念:點陣字體是把每個字符都分紅 n * n 個點,而後用每一個點的虛實來表示字符的輪廓。點陣字體也叫位圖字體,其中每一個字形都以一組二維像素信息表示。app

漢字那麼多,總不能每一個字都去本身設計點陣吧?別擔憂,有現成的點陣字庫能夠直接使用:HZK16字庫。HZK即漢字庫的首字母縮寫,HZK16字庫是符合GB2312標準的16×16點陣字庫,支持的漢字有6763個(但惋惜不支持英文和數字),每一個漢字模型須要16×16一共須要256個點來顯示。svg

這樣思路就出來了:咱們本身輸入漢字,根據字符串中漢字字符編碼,去HZK16字庫中獲取點陣信息,拿到信息後根據16*16點陣每一個點的數據,print 出不一樣字符。學習

Talk is cheap, show me the code字體

#初始化16*16的點陣位置,每一個漢字須要16*16=256個點來表示
rect_list = [] * 16
for i in range(16):
    rect_list.append([] * 16)
#拿「贊」字來演示
text = "贊"
#獲取中文的編碼
gb2312 = text.encode('gb2312')
hex_str = binascii.b2a_hex(gb2312)
result = str(hex_str, encoding='utf-8')
#根據編碼計算「贊」在漢字庫中的位置
area = eval('0x' + result[:2]) - 0xA0
index = eval('0x' + result[2:]) - 0xA0
offset = (94 * (area-1) + (index-1)) * 32
font_rect = None
#讀取HZK16漢字庫文件中「贊」字數據
with open("HZK16", "rb") as f:
    f.seek(offset)
    font_rect = f.read(32)
#根據讀取到HZK中數據給咱們的16*16點陣賦值
for k in range(len(font_rect) // 2):
    row_list = rect_list[k]
    for j in range(2):
        for i in range(8):
            asc = font_rect[k * 2 + j]
            flag = asc & KEYS[i]
            row_list.append(flag)
#根據獲取到的16*16點陣信息,打印到控制檯
for row in rect_list:
    for i in row:
        if i:
            #前景字符(即用來表示漢字筆畫的輸出字符)
            print('0', end=' ')
        else:
            #背景字符(即用來表示背景的輸出字符)
            print('.', end=' ')
    print()
複製代碼

解決了輸出字符的問題,接下來就考慮,如何把這些點換成微信好友頭像呢?flex

咱們經過 itchat 這個開源的微信我的號接口來獲取微信好友頭像圖片。這個在以前的文章《Crossin:用Python寫個了紅包提醒,再不怕錯過一個億了》也使用過。

#經過二維碼登陸微信網頁版
itchat.auto_login()
#獲取微信好友信息列表
friendList = itchat.get_friends(update=True)
#讀取好友頭像
for friend in friendList:
    friend['head_img'] = itchat.get_head_img(userName=friend['UserName'])
    friend['head_img_name'] = "%s.jpg" % friend['UserName']
    #寫入文件
    with open(friend['head_img_name'],'wb') as f:
        f.write(friend['head_img'])
複製代碼

有了頭像以後,咱們經過 PIL (Python Image Library,python的第三方圖像處理庫) 根據漢字點陣信息拼接頭像圖片。核心代碼片斷:

#新建畫布,16*16點陣,每一個圖片邊長100
canvas = Image.new('RGB', (1600, 1600), '#FFFFFF')
n = 0
for i in range(16*16):
    #點陣信息爲1,即表明此處要顯示頭像來組字
    if item[i] == "1":
        # 打開圖片
        img = Image.open(imgList[n])
        # 縮小圖片
        img = img.resize((100, 100), Image.ANTIALIAS)
        # 拼接圖片
        canvas.paste(img, ((i % 16) * 100, (i // 16) * 100))
        n += 1
複製代碼

綜合以上三個步驟,便可用微信好友頭像組成你想要的文字了。

若是你嫌棄這 16x16 的字庫效果,也能夠經過對圖片進行二值化處理,以獲取更精緻的點陣信息來成字符圖。好比這個「福」字,其點陣信息就是我對福字圖片處理獲得的,最終展現的效果也更美觀大方:

咱們也能夠利用歌詞或視頻字幕文件中的時間信息,經過 sleep 控制停頓,實現一個動態展現字幕的功能:

更多玩法歡迎你來一塊兒動手挖掘!

篇幅有限,上述僅爲部分核心代碼的演示。獲取完整代碼以及可直接使用的 exe 文件,可在公衆號(Crossin的編程教室)裏回覆關鍵字 元宵節

----

本文是咱們編程教室新春徵稿活動的一篇投稿,來自 @TED 同窗,若是你常常上咱們的論壇,必定見過這個ID的身影,他常常在上面回答其餘同窗的問題。他本身也開了一個python學習的公衆號:TEDxPY,他的知乎專欄:

TED的Python小寶庫 zhuanlan.zhihu.com圖標

歡迎各位去找他交流學習。

關於點陣字,他連續寫了好幾篇文章。更詳細的分析和代碼,能夠戳連接直達,均提供代碼下載。

今天咱們本次徵稿活動(編程教室2019新春徵稿活動)即將截止,但咱們編程教室會持續向全部人開放,若是有投稿或參與志願者的意向,歡迎隨時在公衆號裏給咱們留言。


════

其餘文章及回答:

如何自學Python | 新手引導 | 一圖學Python | 智能防擋彈幕 | 紅包提醒 | 流浪地球

歡迎搜索及關注:Crossin的編程教室

相關文章
相關標籤/搜索