有趣的Python圖片制作之如何用QQ好友頭像拼接出里昂
在本篇博客中,我們將實(shí)現(xiàn)兩個(gè)功能:
- 將所有頭像合并為大圖
- 將所有頭像以某個(gè)模板合成大圖
同樣,先給上所有運(yùn)行效果圖:
代碼實(shí)現(xiàn)
1、代碼所需庫
import requests,codecs,re,urllib,os,random,math from PIL import Image import numpy as np import cv2 as cv
2、代碼講解
本篇博客就不再講解如何獲取好友頭像了,需要的可以參考這篇博文:
python爬蟲-從QQ郵箱獲取好友信息并爬取頭像
現(xiàn)在,我們已經(jīng)有了所有的好友頭像,接下來我們先實(shí)現(xiàn)對(duì)所有頭像的集合咯
2.1、將小頭像合并為大圖
對(duì)于這個(gè),就是直接將每個(gè)小頭像貼在大圖上就行了,這個(gè)利用Image的paste函數(shù)就可以解決。對(duì)于貼的順序就可以直接按照下面圖示一個(gè)個(gè)貼:
所以,直接給出代碼:
def simple_split(filepackage,size,littlesize): #簡單拼接,參數(shù)為圖片文件名,每行每列的size,小頭像圖片的大小 row = size[0] col = size[1] bigimg = Image.new('RGBA',(littlesize*row,littlesize*col)) #結(jié)果圖 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)
由于好友不多,所以我們每次就隨機(jī)選擇一個(gè)好友頭像貼上去,所以如果你的密度大的話最后出現(xiàn)的頭像有很多重復(fù)的頭像。
給大家展示下最后我的圖片吧:
2.2、以某個(gè)圖片為模板拼接圖片
由于不清楚有沒有能夠直接做出來的第三方庫,所有我就自己造了個(gè)小輪子。
思路:
將模板分為A x B的小圖,就將它的位置形容為 pic[i][j] 吧,然后獲取每個(gè)小圖的平均RGB值,將 pic[i][j] 的平均RGB值和好友頭像的RGB值做對(duì)比,找出最接近的頭像,然后將該頭像插入在圖像的 pic[i][j] 處。
思路還是比較簡單吧😀
接下來就是實(shí)現(xiàn)了:
代碼很多地方都給出了注釋,我就不多講了,直接給出代碼:
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/' #頭像存儲(chǔ)位置 resultSavePath = 'C:/Users/11037/Desktop/result2.png' #結(jié)果存儲(chǔ)位置 modePath = 'C:/Users/11037/Desktop/leno.jpg' #模板存儲(chǔ)位置 friends_count = 0 #好友數(shù)量 all_mean_rgbs = [] #存儲(chǔ)計(jì)算出的所有平均rgb值 def meanrbg(img): #計(jì)算圖片平均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文件存儲(chǔ)位置 file = codecs.open(txtpath,'rb','utf-8') s = file.read() pattern = re.compile(r'\d+@qq.com') all_mail = pattern.findall(s) #正則表達(dá)式匹配所有的qq號(hào) all_link = [] #用于存儲(chǔ)需要訪問的鏈接 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) #獲取朋友頭像數(shù)量 return True def savaImg(picurl,saveurl): #存儲(chǔ)圖片函數(shù),picurl是圖片的URL,saveurl是本地存儲(chǔ)位置 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): #簡單拼接,參數(shù)為圖片文件名,每行每列的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): #以模板存儲(chǔ)頭像 row = bigsize[0] #大圖每行多少個(gè)小頭像 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) #模板剪切用于對(duì)比的某個(gè)區(qū)域 cutImg = bigImg.crop(cutbox) #復(fù)制到cutImg中 tmprgb = meanrbg(cutImg) suitOne = mostSuitImg(tmprgb) + 1 #對(duì)比出最合適的頭像 img = Image.open(filepackage + str(suitOne) + '.png').convert('RGBA') img = img.resize((littlesize,littlesize)) resultImg.paste(img,cutbox) print('已粘貼',cutbox) resultImg.save(resultSavePath) #存儲(chǔ) def mostSuitImg(tmprgb): #進(jìn)行對(duì)比,找出最合適的頭像 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) #獲取頭像,如果已經(jīng)獲取就可以給注釋掉了 # 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)) #給列表增加一個(gè)索引 mode_split(savepath,modePath,(50,80),20) #模板拼接
給大家看看最終的效果:
這樣一看還是都不錯(cuò)是吧。哈哈。
再給出里昂的模板和最終成果:
添加【修改后的Leon】:
我默認(rèn)將每個(gè)頭像以數(shù)字命名,可以便于后續(xù)的操作。
同時(shí),以上代碼都進(jìn)行了封裝,很多函數(shù)都可以獨(dú)立使用,用于滿足不同的功能??梢宰约鹤x完代碼進(jìn)行改寫實(shí)現(xiàn)自己需要的功能,比如說以上我默認(rèn)頭像圖片都是正方形,你如果圖片有長方形的改變下代碼也可以滿足。
理論上來說,你的好友頭像越多,制作出來的圖片與模板的差異也就越小。以mode_split這個(gè)函數(shù)為例,你設(shè)置的bigsize越大,你的圖片也就越清晰。
到此這篇關(guān)于有趣的Python圖片制作之如何用QQ好友頭像拼接出里昂的文章就介紹到這了,更多相關(guān)python 好友頭像拼接內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python Django模板之模板過濾器與自定義模板過濾器示例
這篇文章主要介紹了Python Django模板之模板過濾器與自定義模板過濾器,結(jié)合實(shí)例形式分析了Django框架模板過濾器與自定義模板過濾器相關(guān)功能、原理、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2019-10-10Python構(gòu)造函數(shù)及解構(gòu)函數(shù)介紹
這篇文章主要介紹了Python構(gòu)造函數(shù)及解構(gòu)函數(shù)介紹,本文只是講解構(gòu)造及解構(gòu)函數(shù)的簡單知識(shí),需要的朋友可以參考下2015-02-02python網(wǎng)絡(luò)編程之?dāng)?shù)據(jù)傳輸U(kuò)DP實(shí)例分析
這篇文章主要介紹了python網(wǎng)絡(luò)編程之?dāng)?shù)據(jù)傳輸U(kuò)DP實(shí)現(xiàn)方法,實(shí)例分析了Python基于UDP協(xié)議的數(shù)據(jù)傳輸實(shí)現(xiàn)方法,需要的朋友可以參考下2015-05-05pyqt5實(shí)現(xiàn)繪制ui,列表窗口,滾動(dòng)窗口顯示圖片的方法
今天小編就為大家分享一篇pyqt5實(shí)現(xiàn)繪制ui,列表窗口,滾動(dòng)窗口顯示圖片的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-06-06Pytorch:torch.diag()創(chuàng)建對(duì)角線張量方式
這篇文章主要介紹了Pytorch:torch.diag()創(chuàng)建對(duì)角線張量方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06