Python玩微信头像组字

  • 思路
  • itchat
  • 获取头像图片
  • 汉字转点阵
  • 头像图片拼接
  • 九宫格效果
  • 回顾
  • 代码
  • 最后

上一篇,用Python实现了拿微信好友头像来拼接背景,融合成自己的新头像。

再之前呢,我们也实现了点阵字的输出与展示。

正好今天有位老哥过生日,我就把头像拼接和点阵字结合起来,搞了个头像成字的代码,请看微信朋友圈九宫格效果:
其中,每个字都是16*16的点阵,点阵中每个点可以拆解为4个好友头像图片:

思路

基本思路很直接:读取微信好友头像,按照汉字的点阵信息进行拼接,生成完整的单字图片。

读取微信好友头像的思路上篇提到过:利用开源的微信接口itchat,扫码登录个人微信,读取好友信息中的头像存到本地。

获取汉字的点阵信息也是按照之前的思路:利用汉字库HZK16文件来实现。拿到点阵信息后,将背景图片当做16*16点阵,用头像图片和空白来替代点阵中的点。这里为了提高字笔画的丰富性,我采用一个点对应4个头像图片。

itchat

itchat是一个开源的微信个人号接口,使用python调用微信从未如此简单。

首先是安装 pip install itchat,在代码中import itchat,之后直接调用方法即可。

#通过二维码登录微信网页版
itchat.auto_login()
#获取微信好友信息列表
friendList = itchat.get_friends(update=True)

获取头像图片

通过好友列表中的信息,读取头像图片内容,存储到本地,这样就完成了头像素材的获取。

好友如果很多,这个阶段耗时会较长。此外这个过程中发现有的好友可能没有设置头像、或者头像格式比较特殊,会导致读取失败,这里要利用try except语法进行控制。

汉字转点阵

点阵字体是把每一个字符都分成16×16或24×24个点,然后用每个点的虚实来表示字符的轮廓。点阵字体也叫位图字体,其中每个字形都以一组二维像素信息表示

HZK16字库是符合GB2312标准的16×16点阵字库,支持的汉字有6763个,每个汉字模型需要16×16一共需要256个点来显示。

头像图片拼接

每个头像图片统一裁剪为100*100的小方图,16x16的点阵,每个点是2x2个头像小方图,即最终图片为长16x2x100的方图。

首先通过PIL模块生成背景图,可以设置自己喜欢的颜色:

#如果想要白色背景,将colorlist[index]改为'#FFFFFF'
canvas = Image.new('RGB', (3200, 3200), colorlist[index])  # 新建一块画布

根据汉字的点阵信息,控制是否将头像图片在该位置展现,最终生成头像图片拼接的单字大图。

九宫格效果

微信朋友圈九宫格效果如下,首先是新年祝福:

还有张大吉大利吃鸡九宫格:

回顾

用头像来组字的想法产生挺久了,最开始是想自己设计字形根据笔画来排列头像图片,觉得太辛苦就一直没去做。最近接触了点阵字并用代码来展示后,才有了实现图片组字的信心。 正好碰到朋友过生日,就用代码送上一点心意,比较简陋,但重在心意,感觉还是很不错的。

关于点阵字,从最开始的用0和1来展示,到改变成特殊符号提高美感,再到用tkinter图形界面以规范样式,以及现在用图片来拼点阵字,算是一个纵向自学的过程吧。可能重在乐子而非应用,但这个过程中,用心想了、尽力做了,权当对自己的一种锻炼吧。

代码

代码下载链接

由于每次通过微信下载好友头像图片耗时较长,附加了个单纯用图片组字的代码。

代码文件中添加了注释,也附了个txt文档说明,如果感兴趣可以看看,非常欢迎各种建议和意见~

import binascii
import os
from PIL import Image
import itchatdef char2bit(textStr):KEYS = [0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01]target = []global countcount = 0for x in range(len(textStr)):text = textStr[x]rect_list = [] * 16for i in range(16):rect_list.append([] * 16)gb2312 = text.encode('gb2312')hex_str = binascii.b2a_hex(gb2312)result = str(hex_str, encoding='utf-8')area = eval('0x' + result[:2]) - 0xA0index = eval('0x' + result[2:]) - 0xA0offset = (94 * (area-1) + (index-1)) * 32font_rect = Nonewith open("HZK16", "rb") as f:f.seek(offset)font_rect = f.read(32)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)output = []for row in rect_list:for i in row:if i:output.append('1')count+=1#print('0', end=' ')else:output.append('0')#print('.', end=' ')#print()target.append(''.join(output))return targetdef getHeadImgs():#通过二维码登录微信网页版itchat.auto_login()#获取微信好友信息列表friendList = itchat.get_friends(update=True)#这里会用到的微信好友信息如下: User= {'UserName': '@8238e922e8be7356b1750c306cb75768','PYQuanPin': 'TED','NickName': 'TED'}#获取用户个人昵称,用于之后文件夹命名、用户头像命名if friendList[0]['PYQuanPin']:user = friendList[0]['PYQuanPin']else:user = friendList[0]['NickName']#先读取用户本人头像,存储名为用户名称selfHead = "{}/{}.jpg".format(os.getcwd(),user)with open(selfHead,'wb') as f:head = itchat.get_head_img(friendList[0]['UserName'])f.write(head)#创建文件夹用于存储好友头像if not os.path.exists(user):os.mkdir(user)#工作路径转到新建文件夹中os.chdir(user)#获取新建文件夹路径userspace = os.getcwd()#开始读取好友头像写入新建文件夹中print("开始读取%d位好友头像..."%(len(friendList)-1))for i in range(1,len(friendList)):if i % 100 ==0:print("已读取%d位好友头像,请耐心等待~"%i)try:friendList[i]['head_img'] = itchat.get_head_img(userName=friendList[i]['UserName'])friendList[i]['head_img_name'] = "%s.jpg" % friendList[i]['UserName']except ConnectionError:print('Fail to get %s' % friendList[i]['UserName'])with open(friendList[i]['head_img_name'],'wb') as f:f.write(friendList[i]['head_img'])print("读取好友头像完毕!")#保存头像的文件夹路径和用户本人头像路径返回return user, selfHeaddef head2char(workspace,user,self,outlist):folder = "{}\\{}".format(workspace,user)#将工作路径转移至头像文件夹os.chdir(folder)#获取文件夹内头像列表imgList = os.listdir(folder)#获取头像图片个数numImages = len(imgList)#设置头像裁剪后尺寸eachSize = 100#变量n用于循环遍历头像图片,即当所需图片大于头像总数时,循环使用头像图片n=0#变量count用于为最终生成的单字图片编号count = 0#img = Image.open(self)#初始化颜色列表,用于背景着色:FFFACD黄色 #F0FFFF白  #BFEFFF 蓝  #b7facd青色 #ffe7cc浅橙色  #fbccff浅紫色 #d1ffb8淡绿 #febec0淡红 #E0EEE0灰colorlist = ['#FFFACD','#F0FFFF','#BFEFFF','#b7facd','#ffe7cc','#fbccff','#d1ffb8','#febec0','#E0EEE0']#index用来改变不同字的背景颜色index = 0#每个item对应不同字的点阵信息for item in outlist:#将工作路径转到头像所在文件夹os.chdir(folder)#新建一个带有背景色的画布,16*16点阵,每个点处填充2*2张头像图片,故长为16*2*100#如果想要白色背景,将colorlist[index]改为'#FFFFFF'canvas = Image.new('RGB', (3200, 3200), colorlist[index])  # 新建一块画布#index变换,用于变换背景颜色index = (index+1)%9count += 1#每个16*16点阵中的点,用四张100*100的头像来填充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/4try: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/4try: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/4try: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/4try: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)os.chdir(workspace)# 创建文件夹用于存储输出结果if not os.path.exists('{}_output'.format(user)):os.mkdir('{}_output'.format(user))os.chdir('{}_output'.format(user))#quality代表图片质量,1-100canvas.save('result%d.jpg'% count, quality=100)if __name__=="__main__":#将想转化的字赋给字符串inpt = "生日快乐,事事顺心!"#将字转化为汉字库的点阵数据outlist = char2bit(inpt)#获取当前文件夹路径workspace = os.getcwd()#获取用户本人名称和用户本人头像路径user,self = getHeadImgs()#将头像图片按点阵拼接成单字图片head2char(workspace,user,self,outlist)print("Well done!")

最后

如果觉着还可以,欢迎关注下我学习Python升级的公众号哈~

本着一颗玩Python的心,自己去尝试各种小代码小项目,欢迎组团~

Python玩微信头像组字相关推荐

  1. Python玩微信——头像组字篇

    正好今天有位老哥过生日,结合着微信头像和点阵字,搞了个头像拼字的代码,朋友圈九宫格效果如下: 其中,每个字都是16*16的点阵,点阵中每个点可以拆解为4个好友头像图片: 代码中汉字文本可以自定义输入, ...

  2. python微信头像_Python玩微信——头像组字

    上一篇,用Python实现了拿微信好友头像来拼接背景,融合成自己的新头像. 再之前呢,我们也实现了点阵字的输出与展示. 正好今天有位老哥过生日,我就把头像拼接和点阵字结合起来,搞了个头像成字的代码,请 ...

  3. python代码图片头像_Python玩微信——头像组字篇

    正好今天有位老哥过生日,结合着微信头像和点阵字,搞了个头像拼字的代码,朋友圈九宫格效果如下: 其中,每个字都是16*16的点阵,点阵中每个点可以拆解为4个好友头像图片: 代码中汉字文本可以自定义输入, ...

  4. python 微信_wxpy: 用 Python 玩微信

    wxpy: 用 Python 玩微信¶ 微信机器人 / 可能是最优雅的微信个人号 API wxpy 在 itchat 的基础上,通过大量接口优化提升了模块的易用性,并进行丰富的功能扩展 注意 强烈建议 ...

  5. python头像右上角加红色数字_利用python实现微信头像加红色数字功能

    通过Python实现将你的 QQ 头像(或者微博头像)右上角加上红色的数字,类似于微信未读信息数量那种提示效果. 类似于图中效果 实现过程: 准备两张图片如下: 使用PIL图像处理库,导入moudle ...

  6. Python玩转《生僻字》

    Python玩转<生僻字> 最终效果 思路 pypinyin库 读写txt文本 拼接 回顾 代码下载 最后 茕茕孑立 沆瀣一气 踽踽独行 醍醐灌顶 绵绵瓜瓞 奉为圭臬 龙行龘龘 犄角旮旯 ...

  7. python程序设置头像_利用python实现微信头像加红色数字功能

    通过Python实现将你的 QQ 头像(或者微博头像)右上角加上红色的数字,类似于微信未读信息数量那种提示效果. 类似于图中效果 实现过程: 准备两张图片如下: 使用PIL图像处理库,导入moudle ...

  8. python微信使用教程_小白用Python | 十分钟Python玩微信教程

    原标题:小白用Python | 十分钟Python玩微信教程 代码放在这里:wzyonggege/python-wechat-itchat 词云那里可以换成小黄人图片 ---------------- ...

  9. 用 Python 玩微信,机器人陪你唠嗑

    点击上方"Python爬虫与数据挖掘",进行关注 回复"书籍"即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 月出惊山鸟,时鸣春涧中. 之前给大 ...

最新文章

  1. Java异步执行多个HTTP请求的例子(需要apache http类库)
  2. 利用Log Explorer将你已经delete,truncate,drop过的数据进行恢复
  3. BaiDu校招2016计算机视觉笔试试题
  4. 机器视觉 · 立体相机
  5. 不可摸数http://acm.hdu.edu.cn/showproblem.php?pid=1999
  6. 分析 C# 2.0 新特性 -- 空类型(Nullable Types)
  7. dropdownlist ajax联动,asp.net省市三级联动的DropDownList+Ajax的三种框架(aspnet/Jquery/ExtJs)示例...
  8. wangmarket-master
  9. 扫地机器人水箱背景_你真的懂扫地机器人吗?这些不为人知的小细节值得一看...
  10. linux主机重启之后,报UNEXPECTED INCOMSISTEMCY:RUN fsck MANUALLY.
  11. oracle存储过程捕捉异常后回滚_Oracle存储过程中异常处理应注意的问题
  12. 今日头条下拉词框怎么做的呢?怎么优化推广呢?
  13. 前端实现在线预览Word文件
  14. 贪心算法 --- 例题2.哈夫曼编码问题
  15. Java调用阿里云短信接口发送手机验证码
  16. 教师不能错过的三款教学必备工具
  17. Windows xp定时关机命令
  18. 【长期维护】程序员锻炼法则
  19. [Vmware]VCSA部署及遇到的问题
  20. swiper跳转指定slides,其他路由跳转swiper指定slides

热门文章

  1. linux 16中文输入法,ubuntu 16.04 下安装并切换搜狗中文输入法
  2. python批量删除文件名_Python批量修改文件名(删除指定关键字)
  3. 微信小程序页面始终停留在下拉状态的bug解决
  4. 雨听 | 解决连接蓝牙后谷歌浏览器无声音(其他应用有声音)问题
  5. OpenGL Transform Feedback
  6. SpringBoot+vue+jpa+mysql前后台分离实现增删改查分页和三级联动(附源码)(一)
  7. 56网首发2012APEC青创会主题微电影
  8. GEE学习笔记1:GEE初识
  9. shell字符串切割 去除文件名后缀
  10. STM32的超声波测距程序