SoFunction
Updated on 2024-11-20

Funny Python Image Maker's How to Splicing Lyon with QQ Friends' Avatars

In this blog, we will implement two features:

  • Combine all avatars into a larger image
  • Combine all avatars into a large image with a certain template

Again, all the running results are given first:

在这里插入图片描述

code implementation

1, code required library

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

2、Code Explanation

This blog will not explain how to get your friend's avatar, if you need it, you can refer to this blog post:
Python Crawler - Get friend info from QQ mailbox and crawl avatars.

Now that we have all of our friends' avatars, let's start with a collection of all of them.

在这里插入图片描述

2.1. Merge small avatars into larger ones

For this, it is directly to each small avatar paste in the big picture on the line, the use of Image's paste function can be solved. For the order of the paste can be directly in accordance with the following chart one by one paste:

在这里插入图片描述

So, the code is given directly:

def simple_split(filepackage,size,littlesize): # Simple splicing, parameters are image file name, size of each row and column, size of small avatar image
	row = size[0]
	col = size[1]
	bigimg = ('RGBA',(littlesize*row,littlesize*col)) #Results Chart
	number = 0
	for i in range(row): # rows
		for j in range(col): # columns
			randpic = (1,friends_count)
			img = (filepackage+str(randpic)+'.png').convert('RGBA')
			img = ((littlesize,littlesize))
			loc = (i*littlesize,j*littlesize,(i+1)*littlesize,(j+1)*littlesize)
			print(loc,number)
			number+=1
			(img,loc)
	(resultSavePath)

Since we don't have a lot of friends, we just randomly choose one friend avatar at a time to post, so there are a lot of duplicate avatars that end up appearing if you have a high density.

Let's show you a picture of what I ended up with:

在这里插入图片描述

2.2, to a certain picture as a template splicing picture

Since it's not clear if there are any third party libraries that can do it directly, all I did was build my own little wheel.

Thoughts:
Divide the template into small A x B images, let's describe its position as pic[i][j], then get the average RGB value of each small image, compare the average RGB value of pic[i][j] with that of your friend's avatar, find the closest avatar, and then insert that avatar at pic[i][j] of the image.

The thought process is still relatively simple I guess 😀

The next step is to realize it:

The code is given as comments in many places, so I won't go into it and give the code directly:

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/' # The file you pasted from your QQ mailbox
savepath = 'C:/Users/11037/Desktop/touxiang/' # Avatar storage location

resultSavePath = 'C:/Users/11037/Desktop/'  # Where results are stored
modePath = 'C:/Users/11037/Desktop/'  # Template storage location

friends_count = 0  # of friends
all_mean_rgbs = []  # Stores all average rgb values calculated

def meanrbg(img): # Calculate the average rgb of an image
	rgb = (img)
	r = int(round((rgb[:, :, 0])))
	g = int(round((rgb[:, :, 1])))
	b = int(round((rgb[:, :, 2])))
	return (r,g,b)

def gettouxiang(txtpath):# Enter the location where your txt file is stored
	file = (txtpath,'rb','utf-8')
	s = ()
	pattern = (r'\d+@')
	all_mail = (s) #Regular Expression Match All qq Numbers
	all_link = [] # Used to store links that need to be accessed
	url = '/qzone/'
	for mail in all_mail:
		qq = ('@','')
		l = url + qq +'/'+qq+'/100'
		all_link.append(l)
	i = 1
	for link in all_link:  # Traverse the link and download the avatar
		saveurl = savepath+str(i)+'.png'
		savaImg(link,saveurl)
		i +=1
		print('Downloaded',i)
	friends_count = len(all_link) # Get the number of friends' avatars
	return True

def savaImg(picurl,saveurl): # store image function, picurl is the URL of the image, saveurl is the local storage location
	try:
		bytes = (picurl)
		file = open(saveurl,'wb')
		(())
		()
		()
		return True
	except:
		print('worry')
		savaImg(picurl,saveurl)


def simple_split(filepackage,size,littlesize): # Simple splicing, parameters are image file name, size of each row and column, size of small avatar image
	row = size[0]
	col = size[1]
	bigimg = ('RGBA',(littlesize*row,littlesize*col))
	number = 0
	for i in range(row):
		for j in range(col):
			randpic = (1,friends_count)
			img = (filepackage+str(randpic)+'.png').convert('RGBA')
			img = ((littlesize,littlesize))
			loc = (i*littlesize,j*littlesize,(i+1)*littlesize,(j+1)*littlesize)
			print(loc,number)
			number+=1
			(img,loc)
	(resultSavePath)


def mode_split(filepackage,modepath,bigsize,littlesize): #Store avatars as templates
	row = bigsize[0] #How many small avatars per line of the large image
	col = bigsize[1] # Each column
	suitSize = (littlesize*row,littlesize*col) #The final pixel size of the big picture.
	bigImg = (modepath)
	bigImg = (suitSize)
	resultImg = ('RGBA',suitSize) 

	for i in range(row):
		for j in range(col):
			cutbox = (i*littlesize,j*littlesize,(i+1)*littlesize,(j+1)*littlesize) # Template clipping is used to compare an area
			cutImg = (cutbox) #Copy to cutImg
			tmprgb = meanrbg(cutImg) 
			suitOne = mostSuitImg(tmprgb) + 1 #Compare the best avatars

			img = (filepackage + str(suitOne) + '.png').convert('RGBA')
			img = ((littlesize,littlesize))
			(img,cutbox)
			print('Pasted',cutbox)
	(resultSavePath) #Storage


def mostSuitImg(tmprgb): #Compare and contrast to find the most suitable avatar
	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) # get the avatar, if you've already got it, you can comment it out.
	# simple_split(savepath,(20,20),30) #simple_split
	
	# Template splicing
	for i in range(1,friends_count+1):
		img = (savepath+str(i)+'.png')
		rgb = meanrbg(img)
		all_mean_rgbs.append(rgb)
	all_mean_rgbs = list(enumerate(all_mean_rgbs)) # Add an index to the list
	
	mode_split(savepath,modePath,(50,80),20) #stencil splice

To show you the final result:

在这里插入图片描述

It's still all good at this point, right? Ha ha.

Give Lyon's template and final results again:

在这里插入图片描述
在这里插入图片描述
Add [modified Leon]:
在这里插入图片描述

I default to naming each avatar with a number, which can be easy to follow.

At the same time, the above code is encapsulated, many functions can be used independently to meet different functions. You can read the code to rewrite their own needs to achieve the function, for example, the above my default avatar image are square, you if the picture has a rectangular change under the code can also meet.

Theoretically, the more avatars you have of your friends, the smaller the difference between the produced image and the template. Take the function mode_split for example, the bigger the bigsize you set, the clearer your image will be.

To this interesting Python image production of how to use QQ friends avatars spliced Leon article is introduced to this, more related python friends avatars splicing content please search for my previous articles or continue to browse the following related articles I hope that you will support me more in the future!