python?HZK16字庫使用詳解
環(huán)境: windows7, python2.7
簡介
偶然在網(wǎng)上看到熱心網(wǎng)友使用python講微信頭像進(jìn)行了組字,感覺很有意思,就做下研究。
感謝,原文參考自: Python玩微信頭像組字
需求的相關(guān)工具:
python第三方庫image
pip install image # 圖像處理
HZK16字庫的下載
自行百度下載吧,由于網(wǎng)盤鏈接失效暫不給大家分享了。
本應(yīng)該要安裝python的第三方庫itchat的
pip install itchat # 開源的微信個(gè)人接口 # 騰訊在2019年7月份關(guān)閉了網(wǎng)頁版登錄接口 # itchat的相關(guān)接口已經(jīng)不能夠正常使用了,原有使用的主要接口有: # 自動(dòng)登錄微信網(wǎng)頁,會(huì)生成一個(gè)二維碼圖片,手機(jī)掃碼即可登入 itchat.auto_login() # 獲取微信好友信息列表,從而獲取頭像信息 friendList = itchat.get_friends(update=True)
實(shí)現(xiàn)的原理:
通過itchat獲取微信好友頭像圖片,將設(shè)定的文字按照HZK16字庫轉(zhuǎn)換為矩陣信息,然后在每個(gè)矩陣點(diǎn)上放置2X2張圖片,最后通過Image生成出來。
雖然itchat不可使用了,但是我們可以使用本地的圖片進(jìn)行模擬效果.
HZK16簡介
它是符合GB2312國家標(biāo)準(zhǔn)的16×16點(diǎn)陣字庫,每個(gè)漢字需要**256(16×16)**個(gè)點(diǎn)組成。
其GB2312-80支持的漢字有6763個(gè),符號(hào)682個(gè);其中一級(jí)漢字有 3755個(gè),按聲序排列,二級(jí)漢字有3008個(gè),按偏旁部首排列。
通常情況下中文漢字,在UTF-8格式下占用字節(jié)為2個(gè);在GBK,GB2312格式下占用字節(jié)3個(gè)。因此GB2312的HZK16下的中文漢字占用2個(gè)字節(jié)。其編碼范圍:0xA1A1~0xFEFE,A1-A9為符號(hào)區(qū),B0-F7為漢字區(qū)。
前面說到GB2312格式下漢字占2個(gè)字節(jié),前一個(gè)字節(jié)為該漢字的區(qū)號(hào),每個(gè)區(qū)中記錄94個(gè)漢字;后一個(gè)字節(jié)為該字的位號(hào)。用于記錄漢字在該區(qū)中的位置。
因此要找到一個(gè)漢字在HZK16字庫中的位置就必須得到它的區(qū)碼和位碼。
- 區(qū)碼:
漢字的第一個(gè)字節(jié) - 0xA0,因?yàn)闈h字編碼是從0xA0區(qū)開始的,所以文件最前面就是從0xA0區(qū)開始,要算出相對(duì)區(qū)碼 - 位碼:
漢字的第二個(gè)字節(jié) - 0xA0
通過區(qū)碼和位碼我們就可以得到漢字在HZK16中的絕對(duì)偏移位置:
''' * 區(qū)碼或者位碼減1,是由于數(shù)組從0開始,而區(qū)號(hào)位號(hào)是以1開始 * (94*(區(qū)號(hào)-1)+位號(hào)-1)是一個(gè)漢字字模占用的字節(jié)數(shù) * 乘以32是因?yàn)橐粋€(gè)漢字由32個(gè)字節(jié)存儲(chǔ)(16*16/8) ''' offset = (94*(區(qū)碼-1)+(位碼-1))*32
案例:
下載HZK16文件后,放置到指定的目錄中,其目錄結(jié)構(gòu)為:

res中放置著一張75X75的png圖片,可放置多個(gè)。代碼為:
# -*- coding:UTF-8 -*-
#!/usr/bin/env python
import os
import math
import binascii
from PIL import Image
# 用于解決錯(cuò)誤:UnicodeEncodeError: 'ascii' codec encode characters in position...
# 原因在于調(diào)用ascii編碼處理字符流時(shí),若字符流不屬于ascii范圍內(nèi)就會(huì)報(bào)錯(cuò)
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
# 每張頭像裁剪后尺寸,建議圖片不要太大,最好寬高一致
HEAD_CLIPSIZE = 75
# 每行列頭像數(shù)目,即每點(diǎn):2*2,可修改為3,即3*3
HEAD_NUM = 2
RECT_WIDTH = 16 # 矩陣點(diǎn)寬度 16
RECT_HEIGHT = 16 # 矩陣點(diǎn)高度 16
BYTE_COUNT_PER_FONT = 2*RECT_HEIGHT # 占用字節(jié) 32
# 將文字轉(zhuǎn)換為點(diǎn)陣
def char2bit(textStr):
KEYS = [0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01]
target = []
global count
count = 0
# 遍歷文字
for x in range(len(textStr)):
text = textStr[x]
# 初始化16*16點(diǎn)陣位置
rect_list = [] * RECT_WIDTH
for i in range(RECT_HEIGHT):
rect_list.append([] * RECT_WIDTH)
# 獲取GB2312編碼字符
gb2312 = text.encode('gb2312')
hex_str = binascii.b2a_hex(gb2312)
result = str(hex_str)
# 獲取漢字第一個(gè)字節(jié),區(qū)碼
area = eval('0x' + result[:2]) - 0xA0
# 獲取漢字第二個(gè)字節(jié),位碼
index = eval('0x' + result[2:]) - 0xA0
# 獲取漢字在字庫中的絕對(duì)偏移值
offset = (94 * (area-1) + (index-1)) * BYTE_COUNT_PER_FONT
font_rect = None
# 讀取HZK16字庫文件
with open("HZK16", "rb") as f:
# 獲取目標(biāo)漢字偏移位置
f.seek(offset)
# 從數(shù)據(jù)中讀取32字節(jié)數(shù)據(jù)
font_rect = f.read(BYTE_COUNT_PER_FONT)
for k in range(len(font_rect)/2):
row_list = rect_list[k]
for j in range(2):
for i in range(8):
asc = binascii.b2a_hex(font_rect[k * 2 + j])
asc = asc = eval('0x' + asc)
flag = asc & KEYS[i]
row_list.append(flag)
output = []
_str = ''
for row in rect_list:
for i in row:
if i:
output.append('1')
_str += '0'
count+=1
else:
output.append('0')
_str += '.'
print(_str)
_str = ''
target.append(''.join(output))
return target
def head2char(index, outlist):
# 獲取資源列表
imgList = []
workspace = os.getcwd()
respath = os.path.join(workspace, 'res')
for root, dirs, files in os.walk(respath):
for filename in files:
imgList.append(os.path.join(root, filename))
# 圖片數(shù)目
imgCount = len(imgList)
#變量n用于循環(huán)遍歷頭像圖片,即當(dāng)所需圖片大于頭像總數(shù)時(shí),循環(huán)使用頭像圖片
n = 0
for item in outlist:
# 創(chuàng)建新圖片
canvasWidth = RECT_WIDTH * HEAD_NUM * HEAD_CLIPSIZE
canvasHeight = RECT_HEIGHT * HEAD_NUM * HEAD_CLIPSIZE
canvas = Image.new('RGB', (canvasWidth, canvasHeight), '#E0EEE0')
# 遍歷 RECT_WIDTH * RECT_HEIGHT 矩陣
for i in range(RECT_WIDTH * RECT_HEIGHT):
#點(diǎn)陣信息為1,即代表此處要顯示頭像來組字
if item[i] != '1':
continue
# 每個(gè)點(diǎn)使用放置幾個(gè)矩陣,比如2*2,3*3
for count in range(pow(HEAD_NUM, 2)):
# 獲取圖片索引
imgIndex = (n + count) % imgCount
# 讀取圖片
headImg = Image.open(imgList[imgIndex])
# 重置圖片大小
headImg = headImg.resize((HEAD_CLIPSIZE, HEAD_CLIPSIZE), Image.ANTIALIAS)
# 拼接圖片
posx = ((i % RECT_WIDTH) * HEAD_NUM + (count%HEAD_NUM)) * HEAD_CLIPSIZE
posy = ((i // RECT_HEIGHT) * HEAD_NUM + (count//HEAD_NUM)) * HEAD_CLIPSIZE
canvas.paste(headImg, (posx, posy))
#調(diào)整n以讀取后續(xù)圖片
n = (n+4) % imgCount
# 保存圖片 quality代表圖片質(zhì)量,1-100
canvas.save('result_{0}.jpg'.format(index), quality=100)
# 將gbk轉(zhuǎn)換為unicode格式
def transGbk2Unicode(str_v):
str_s = str_v.replace(r'%', r'\x')
res = eval(repr(str_s).replace('\\\\', '\\'))
return res.decode('gb2312')
if __name__=="__main__":
inputStr = u'請(qǐng)輸入您想要生成的文字(ENTER結(jié)束):'
# 輸入內(nèi)容,將中文從unicode轉(zhuǎn)換為gbk,防止亂碼
content = raw_input(inputStr.encode('gbk'))
# 將gbk轉(zhuǎn)換為unicode,以方便遍歷時(shí)能夠遍歷每個(gè)文字或字母
content = transGbk2Unicode(content)
print(u'注意:指定文字每個(gè)僅能生成一個(gè)')
# 循環(huán)遍歷
index = 0
for _str in content:
print(u'生成漢字:' + _str)
#將字轉(zhuǎn)化為漢字庫的點(diǎn)陣數(shù)據(jù)
outlist = char2bit(_str)
#將頭像圖片按點(diǎn)陣拼接成單字圖片
head2char(index, outlist)
index += 1
print(u'生成成功!!!')
執(zhí)行結(jié)果:


參考資料:
python實(shí)現(xiàn)點(diǎn)陣字體讀取與轉(zhuǎn)換
到此這篇關(guān)于python HZK16字庫使用的文章就介紹到這了,更多相關(guān)python HZK16字庫內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python提取特定時(shí)間段內(nèi)數(shù)據(jù)的方法實(shí)例
今天小編就為大家分享一篇關(guān)于Python提取特定時(shí)間段內(nèi)數(shù)據(jù)的方法實(shí)例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-04-04
CoordConv實(shí)現(xiàn)卷積加上坐標(biāo)實(shí)例詳解
這篇文章主要介紹了CoordConv實(shí)現(xiàn)卷積加上坐標(biāo)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
python利用后綴表達(dá)式實(shí)現(xiàn)計(jì)算器功能
這篇文章主要為大家詳細(xì)介紹了python利用后綴表達(dá)式實(shí)現(xiàn)計(jì)算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-02-02
python使用pil庫實(shí)現(xiàn)圖片合成實(shí)例代碼
這篇文章主要介紹了python PIL實(shí)現(xiàn)圖片合成實(shí)例代碼,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01
python?selenium在打開的瀏覽器中動(dòng)態(tài)調(diào)整User?Agent
這篇文章主要介紹的是python?selenium在打開的瀏覽器中動(dòng)態(tài)調(diào)整User?Agent,具體相關(guān)資料請(qǐng)需要的朋友參考下面文章詳細(xì)內(nèi)容,希望對(duì)你有所幫助2022-02-02
python之模擬鼠標(biāo)鍵盤動(dòng)作具體實(shí)現(xiàn)
這篇文章主要介紹了python之模擬鼠標(biāo)鍵盤動(dòng)作具體實(shí)現(xiàn),有需要的朋友可以參考一下2013-12-12

