前几天是中秋节,结合着微信好友头像和点阵字,搞了个头像拼字的代码,朋友圈九宫格效果如下:
反响不错
每个字都是16*16的点阵,点阵中每个点由4张微信好友头像图片组成。
代码中汉字可以自定义,头像图片也可以是你准备的其他图片。
整体思路:
- 获取微信好友头像
- 用头像生成点阵字
获取微信好友头像
以前我们可以利用开源的微信接口itchat,扫码登录个人微信,读取好友信息中的头像存到本地。但是这个开源方案有个致命缺点那就是需要登录网页微信,可是现在网页微信已经不能登录了。
所以我们需要换一个思路,我们可以从Win版的微信入手,通过摸索得到一个好消息Win版微信会在用户目录下缓存微信好友头像信息,我们只需要找到并拷贝这些头像即可。
获取微信好友头像核心代码如下
def get_weixin_HeadImage(): """ 获取windows电脑上微信的好友头像、并拷贝到当前目录下 """ username = os.environ['USERNAME'] #获取windows登录用户 filepath = r'C:\Users\{}\Documents\WeChat Files'.format(username) # 用户os.walk函数遍历文件夹,输出所有文件绝对路径 for dirpath, dirname, files in os.walk(filepath): filename = f'{dirpath}' # print(f'发现文件夹:{dirpath}') # print(filename) # 判断是否有微信头像的绝对路径 if 'General\HDHeadImage' in filename: print('微信头像目录:', filename) shutil.copytree(filename, './image', dirs_exist_ok=True) #dirs_exist_ok=True就算文件夹存在也会拷贝 # files = os.listdir('./image') # num_jpg = len(files) num_jpg = len(os.listdir('./image')) #用os.listdir方法获取文件列表 print('找到好友头像数量:', num_jpg) print('拷贝微信好友头像完成') os.system('pause') #手动退出提示
自此我们完成了第一步,获取所有微信好友头像。
用头像生成汉字
首先需要了解一下什么是点阵字
点阵字体是把每一个字符都分成16×16或24×24个点,然后用每个点的虚实来表示字符的轮廓。点阵字体也叫位图字体,其中每个字形都以一组二维像素信息表示。
获取汉字点阵信息思路
利用汉字库HZK16文件来实现。拿到点阵信息后,将背景图片当做16*16点阵,用头像图片和空白来替代点阵中的点。这里为了提高字笔画的丰富性,采用一个点对应4个图片。
HZK16字库
HZK即汉字库的首字母缩写,HZK16字库是符合GB2312标准的16×16点阵字库,支持的汉字有6763个,每个汉字模型需要16×16一共需要256个点来显示,每个点是二进制位也就是2的256次方数据,即32个字节。
github上有很多用图片生成点阵字代码,我们拷贝下来简单修改就能用。
核心代码如下
for i in range(16*16): #点阵信息为1,即代表此处要显示头像来组字 if item[i] == "1": #循环读取连续的四张头像图片 x1 = n % len(imgList) x2 = (n+1) % len(imgList) x3 = (n+2) % len(imgList) x4 = (n+3) % len(imgList) #以下四组try,将读取到的四张头像填充到画板上对应的一个点位置 #点阵处左上角图片1/4 try: img = Image.open(imgList[x1]) # 打开图片 except IOError: print("有1张图片读取失败,已使用备用图像替代") img = Image.open(self) finally: img = img.resize((eachSize, eachSize), Image.ANTIALIAS) # 缩小图片 canvas.paste(img, ((i % 16) * 2 * eachSize, (i // 16) * 2 * eachSize)) # 拼接图片 # 点阵处右上角图片2/4 try: img = Image.open(imgList[x2]) # 打开图片 except IOError: print("有1张图片读取失败,已使用备用图像替代") img = Image.open(self) finally: img = img.resize((eachSize, eachSize), Image.ANTIALIAS) # 缩小图片 canvas.paste(img, (((i % 16) * 2 + 1) * eachSize, (i // 16) * 2 * eachSize)) # 拼接图片 # 点阵处左下角图片3/4 try: img = Image.open(imgList[x3]) # 打开图片 except IOError: print("有1张图片读取失败,已使用备用图像替代") img = Image.open(self) finally: img = img.resize((eachSize, eachSize), Image.ANTIALIAS) # 缩小图片 canvas.paste(img, ((i % 16) * 2 * eachSize, ((i // 16) * 2 + 1 ) * eachSize)) # 拼接图片 # 点阵处右下角图片4/4 try: img = Image.open(imgList[x4]) # 打开图片 except IOError: print("有1张图片读取失败,已使用备用图像替代") img = Image.open(self) finally: img = img.resize((eachSize, eachSize), Image.ANTIALIAS) # 缩小图片 canvas.paste(img, (((i % 16) * 2 + 1) * eachSize, ((i // 16) * 2 + 1) * eachSize)) # 拼接图片 #调整n以读取后续图片 n= (n+4) % len(imgList)
实际效果图
注意事项:
- 如果文字太多,图片太少就会出现一张图片重复出现的情况
- 如果文字太少,图片太多就会出现漏图片的情况
完整代码:
https://github.com/huaisha1224/Python-Example