在本篇博客中,我们将实现两个功能:
- 将所有头像合并为大图
- 将所有头像以某个模板合成大图
同样,先给上所有运行效果图:
代码实现
1、代码所需库
import requests,codecs,re,urllib,os,random,math from PIL import Image import numpy as np import cv2 as cv
2、代码讲解
本篇博客就不再讲解如何获取好友头像了,需要的可以参考这篇博文:
python爬虫-从QQ邮箱获取好友信息并爬取头像
现在,我们已经有了所有的好友头像,接下来我们先实现对所有头像的集合咯
2.1、将小头像合并为大图
对于这个,就是直接将每个小头像贴在大图上就行了,这个利用Image的paste函数就可以解决。对于贴的顺序就可以直接按照下面图示一个个贴:
所以,直接给出代码:
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)
由于好友不多,所以我们每次就随机选择一个好友头像贴上去,所以如果你的密度大的话最后出现的头像有很多重复的头像。
给大家展示下最后我的图片吧:
2.2、以某个图片为模板拼接图片
由于不清楚有没有能够直接做出来的第三方库,所有我就自己造了个小轮子。
思路:
将模板分为A x B的小图,就将它的位置形容为 pic[i][j] 吧,然后获取每个小图的平均RGB值,将 pic[i][j] 的平均RGB值和好友头像的RGB值做对比,找出最接近的头像,然后将该头像插入在图像的 pic[i][j] 处。
思路还是比较简单吧"htmlcode">
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) #模板拼接
给大家看看最终的效果:
这样一看还是都不错是吧。哈哈。
再给出里昂的模板和最终成果:
我默认将每个头像以数字命名,可以便于后续的操作。
同时,以上代码都进行了封装,很多函数都可以独立使用,用于满足不同的功能。可以自己读完代码进行改写实现自己需要的功能,比如说以上我默认头像图片都是正方形,你如果图片有长方形的改变下代码也可以满足。
理论上来说,你的好友头像越多,制作出来的图片与模板的差异也就越小。以mode_split这个函数为例,你设置的bigsize越大,你的图片也就越清晰。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]