有趣的Python图片制作之如何用QQ好友头像拼接出里昂


Posted in Python onApril 22, 2020

在本篇博客中,我们将实现两个功能:

  • 将所有头像合并为大图
  • 将所有头像以某个模板合成大图

同样,先给上所有运行效果图:

有趣的Python图片制作之如何用QQ好友头像拼接出里昂

代码实现

1、代码所需库

import requests,codecs,re,urllib,os,random,math
from PIL import Image
import numpy as np
import cv2 as cv

2、代码讲解

本篇博客就不再讲解如何获取好友头像了,需要的可以参考这篇博文:
python爬虫-从QQ邮箱获取好友信息并爬取头像

现在,我们已经有了所有的好友头像,接下来我们先实现对所有头像的集合咯

有趣的Python图片制作之如何用QQ好友头像拼接出里昂

2.1、将小头像合并为大图

对于这个,就是直接将每个小头像贴在大图上就行了,这个利用Image的paste函数就可以解决。对于贴的顺序就可以直接按照下面图示一个个贴:

有趣的Python图片制作之如何用QQ好友头像拼接出里昂

所以,直接给出代码:

def simple_split(filepackage,size,littlesize): #简单拼接,参数为图片文件名,每行每列的size,小头像图片的大小
	row = size[0]
	col = size[1]
	bigimg = Image.new('RGBA',(littlesize*row,littlesize*col)) #结果图
	number = 0
	for i in range(row): #行
		for j in range(col): #列
			randpic = random.randint(1,friends_count)
			img = Image.open(filepackage+str(randpic)+'.png').convert('RGBA')
			img = img.resize((littlesize,littlesize))
			loc = (i*littlesize,j*littlesize,(i+1)*littlesize,(j+1)*littlesize)
			print(loc,number)
			number+=1
			bigimg.paste(img,loc)
	bigimg.save(resultSavePath)

由于好友不多,所以我们每次就随机选择一个好友头像贴上去,所以如果你的密度大的话最后出现的头像有很多重复的头像。

给大家展示下最后我的图片吧:

有趣的Python图片制作之如何用QQ好友头像拼接出里昂

2.2、以某个图片为模板拼接图片

由于不清楚有没有能够直接做出来的第三方库,所有我就自己造了个小轮子。

思路:
将模板分为A x B的小图,就将它的位置形容为 pic[i][j] 吧,然后获取每个小图的平均RGB值,将 pic[i][j] 的平均RGB值和好友头像的RGB值做对比,找出最接近的头像,然后将该头像插入在图像的 pic[i][j] 处。

思路还是比较简单吧?

接下来就是实现了:

代码很多地方都给出了注释,我就不多讲了,直接给出代码:

import requests,codecs,re,urllib,os,random,math
from PIL import Image
import numpy as np
import cv2 as cv

txtpath = 'C:/Users/11037/Desktop/test/qqfriends.txt' #你从QQ邮箱中粘贴的文件
savepath = 'C:/Users/11037/Desktop/touxiang/' #头像存储位置

resultSavePath = 'C:/Users/11037/Desktop/result2.png'  #结果存储位置
modePath = 'C:/Users/11037/Desktop/leno.jpg'  #模板存储位置

friends_count = 0  #好友数量
all_mean_rgbs = []  #存储计算出的所有平均rgb值

def meanrbg(img): #计算图片平均rgb
	rgb = np.array(img)
	r = int(round(np.mean(rgb[:, :, 0])))
	g = int(round(np.mean(rgb[:, :, 1])))
	b = int(round(np.mean(rgb[:, :, 2])))
	return (r,g,b)

def gettouxiang(txtpath):#输入你的txt文件存储位置
	file = codecs.open(txtpath,'rb','utf-8')
	s = file.read()
	pattern = re.compile(r'\d+@qq.com')
	all_mail = pattern.findall(s) #正则表达式匹配所有的qq号
	all_link = [] #用于存储需要访问的链接
	url = 'http://qlogo.store.qq.com/qzone/'
	for mail in all_mail:
		qq = mail.replace('@qq.com','')
		l = url + qq +'/'+qq+'/100'
		all_link.append(l)
	i = 1
	for link in all_link:  #遍历链接,下载头像
		saveurl = savepath+str(i)+'.png'
		savaImg(link,saveurl)
		i +=1
		print('已下载',i)
	friends_count = len(all_link) #获取朋友头像数量
	return True

def savaImg(picurl,saveurl): #存储图片函数,picurl是图片的URL,saveurl是本地存储位置
	try:
		bytes = urllib.request.urlopen(picurl)
		file = open(saveurl,'wb')
		file.write(bytes.read())
		file.flush()
		file.close()
		return True
	except:
		print('worry')
		savaImg(picurl,saveurl)


def simple_split(filepackage,size,littlesize): #简单拼接,参数为图片文件名,每行每列的size,小头像图片的大小
	row = size[0]
	col = size[1]
	bigimg = Image.new('RGBA',(littlesize*row,littlesize*col))
	number = 0
	for i in range(row):
		for j in range(col):
			randpic = random.randint(1,friends_count)
			img = Image.open(filepackage+str(randpic)+'.png').convert('RGBA')
			img = img.resize((littlesize,littlesize))
			loc = (i*littlesize,j*littlesize,(i+1)*littlesize,(j+1)*littlesize)
			print(loc,number)
			number+=1
			bigimg.paste(img,loc)
	bigimg.save(resultSavePath)


def mode_split(filepackage,modepath,bigsize,littlesize): #以模板存储头像
	row = bigsize[0] #大图每行多少个小头像
	col = bigsize[1] #每列
	suitSize = (littlesize*row,littlesize*col) #大图最终的像素size
	bigImg = Image.open(modepath)
	bigImg = bigImg.resize(suitSize)
	resultImg = Image.new('RGBA',suitSize) 

	for i in range(row):
		for j in range(col):
			cutbox = (i*littlesize,j*littlesize,(i+1)*littlesize,(j+1)*littlesize) #模板剪切用于对比的某个区域
			cutImg = bigImg.crop(cutbox) #复制到cutImg中
			tmprgb = meanrbg(cutImg) 
			suitOne = mostSuitImg(tmprgb) + 1 #对比出最合适的头像

			img = Image.open(filepackage + str(suitOne) + '.png').convert('RGBA')
			img = img.resize((littlesize,littlesize))
			resultImg.paste(img,cutbox)
			print('已粘贴',cutbox)
	resultImg.save(resultSavePath) #存储


def mostSuitImg(tmprgb): #进行对比,找出最合适的头像
	global all_mean_rgbs
	minRange = 200000
	id = 0
	for rgb in all_mean_rgbs:
		tmp = (rgb[1][0]-tmprgb[2])**2+(rgb[1][1]-tmprgb[1])**2+(rgb[1][2]-tmprgb[1])**2
		if tmp<minRange:
			minRange = tmp
			id = rgb[0]
	return id


if __name__ == '__main__':
	# gettouxiang(txtpath)  #获取头像,如果已经获取就可以给注释掉了
	# simple_split(savepath,(20,20),30)  #简单拼接
	
	#模板拼接
	for i in range(1,friends_count+1):
		img = cv.imread(savepath+str(i)+'.png')
		rgb = meanrbg(img)
		all_mean_rgbs.append(rgb)
	all_mean_rgbs = list(enumerate(all_mean_rgbs)) #给列表增加一个索引
	
	mode_split(savepath,modePath,(50,80),20) #模板拼接

给大家看看最终的效果:

有趣的Python图片制作之如何用QQ好友头像拼接出里昂

这样一看还是都不错是吧。哈哈。

再给出里昂的模板和最终成果:

有趣的Python图片制作之如何用QQ好友头像拼接出里昂
有趣的Python图片制作之如何用QQ好友头像拼接出里昂
添加【修改后的Leon】:
有趣的Python图片制作之如何用QQ好友头像拼接出里昂

我默认将每个头像以数字命名,可以便于后续的操作。

同时,以上代码都进行了封装,很多函数都可以独立使用,用于满足不同的功能。可以自己读完代码进行改写实现自己需要的功能,比如说以上我默认头像图片都是正方形,你如果图片有长方形的改变下代码也可以满足。

理论上来说,你的好友头像越多,制作出来的图片与模板的差异也就越小。以mode_split这个函数为例,你设置的bigsize越大,你的图片也就越清晰。

到此这篇关于有趣的Python图片制作之如何用QQ好友头像拼接出里昂的文章就介绍到这了,更多相关python 好友头像拼接内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
用python分割TXT文件成4K的TXT文件
May 23 Python
深入理解Python 代码优化详解
Oct 27 Python
python使用mysql数据库示例代码
May 21 Python
python3+dlib实现人脸识别和情绪分析
Apr 21 Python
django认证系统实现自定义权限管理的方法
Jul 16 Python
在PyCharm导航区中打开多个Project的关闭方法
Jan 17 Python
情人节快乐! python绘制漂亮玫瑰
Aug 18 Python
深入了解Django中间件及其方法
Jul 26 Python
python函数声明和调用定义及原理详解
Dec 02 Python
PyCharm下载和安装详细步骤
Dec 17 Python
Python 解析pymysql模块操作数据库的方法
Feb 18 Python
Ubuntu20.04环境安装tensorflow2的方法步骤
Jan 29 Python
python模拟斗地主发牌
Apr 22 #Python
matlab 计算灰度图像的一阶矩,二阶矩,三阶矩实例
Apr 22 #Python
python根据完整路径获得盘名/路径名/文件名/文件扩展名的方法
Apr 22 #Python
matlab中二维插值函数interp2的使用详解
Apr 22 #Python
python 一维二维插值实例
Apr 22 #Python
Numpy一维线性插值函数的用法
Apr 22 #Python
python数据处理——对pandas进行数据变频或插值实例
Apr 22 #Python
You might like
php mysql数据库操作分页类
2008/06/04 PHP
php检查日期函数checkdate用法实例
2015/03/19 PHP
PHP常见的6个错误提示及解决方法
2016/07/07 PHP
jQuery对表单元素的取值和赋值操作代码
2011/05/19 Javascript
JavaScript实现url地址自动检测并添加URL链接示例代码
2013/11/12 Javascript
jQuery Easyui datagrid连续发送两次请求问题
2016/12/13 Javascript
利用Vue.js实现checkbox的全选反选效果
2017/01/18 Javascript
js中作用域的实例解析
2017/03/16 Javascript
JS中的三个循环小结
2017/06/20 Javascript
Javascript Promise用法详解
2018/05/10 Javascript
微信小程序项目实践之主页tab选项实现
2018/07/18 Javascript
使用VUE+iView+.Net Core上传图片的方法示例
2019/01/04 Javascript
微信小程序按顺序同步执行的两种方式
2019/12/20 Javascript
Vue的双向数据绑定实现原理解析
2020/02/17 Javascript
基于JavaScript实现随机点名器
2021/02/25 Javascript
[04:31]2016国际邀请赛中国区预选赛妖精采访
2016/06/27 DOTA
Python3调用微信企业号API发送文本消息代码示例
2017/11/10 Python
Python生成短uuid的方法实例详解
2018/05/29 Python
python 查找文件名包含指定字符串的方法
2018/06/05 Python
python中int与str互转方法
2018/07/02 Python
python代码打印100-999之间的回文数示例
2019/11/24 Python
基于python 凸包问题的解决
2020/04/16 Python
python中添加模块导入路径的方法
2021/02/03 Python
CSS3中的注音对齐属性ruby-align用法指南
2016/07/01 HTML / CSS
html5中audio支持音频格式的解决方法
2018/08/24 HTML / CSS
Canvas图片分割效果的实现
2019/07/29 HTML / CSS
video下autoplay属性无效的解决方法(添加muted属性)
2020/05/19 HTML / CSS
美国知名艺术画网站:Art.com
2017/02/09 全球购物
美国婚礼和派对礼品网站:Kate Aspen(新娘送礼会、迎婴派对)
2018/03/28 全球购物
英国领先的男装设计师服装独立零售商:Repertoire Fashion
2020/10/19 全球购物
个人自荐信
2013/12/05 职场文书
管理部部长岗位职责
2013/12/05 职场文书
革命英雄事迹演讲稿
2014/09/13 职场文书
喋血孤城观后感
2015/06/08 职场文书
2015最新婚礼主持词
2015/06/30 职场文书
Django 如何实现文件上传下载
2021/04/08 Python