python+PIL批量制作淘宝主图(头图)及满屏水印添加

导读

项目中需要用到图片批量化处理,所以玩了下PIL做了个简单的小项目,解放双手批量制作淘宝主图的功能

任务目标

  • 根据传入的图片数量,自动放大缩小寻找计算可对齐的中心点进行裁切
  • 按照传入图片数量,定制化排版图片
  • 生成模糊背景,以及标题遮罩,根据输入的文字标题信息,自动定位排版标题位置

效果预览及核心代码逻辑

  1. 如果只传入一张图片的话,展示效果,包括核心代码实现
    在这里插入图片描述
# 如果传入一张图片 就复制一份在中间缩略 另外一张底部平铺模糊
if(num == 1):
	new_im = self.resizeImage(ims[0],bw,bh)
	ft.paste(new_im, (0, 0)) # 模糊底图
	pass
  1. 如果传入两张图片的话,展示效果,包括核心代码实现

在这里插入图片描述

# 如果传入两张图片 就在对角各展示一张
elif(num == 2):
	scale = 0.5
	new_im_1 = self.resizeImage(ims[0],int(bw*scale),int(bh*scale))
	new_im_1_copy = new_im_1.copy()
	new_im_2 = self.resizeImage(ims[1],int(bw*scale),int(bh*scale))
	new_im_2_copy = new_im_2.copy()

	ft.paste(new_im_1, (-lineW, -lineW)) #左上
	ft.paste(new_im_2, (int(bw*scale)+lineW, -lineW)) #右上
	ft.paste(new_im_2, (-lineW, int(bh*scale)+lineW)) #左下
	ft.paste(new_im_1, (int(bw*scale)+lineW, int(bh*scale)+lineW)) #右下
	pass
  1. 如果传入的是三张图片 横着两张 竖着三张排列
    在这里插入图片描述
# 如果传入的是三张图片 
elif(num == 3):

	xw = int(bw/2)
	xh = int(bh/num)

	new_im_1 = self.resizeImage(ims[0],xw,xh)
	new_im_2 = self.resizeImage(ims[1],xw,xh)
	new_im_3 = self.resizeImage(ims[2],xw,xh)

	ft.paste(new_im_1, (-lineW, -lineW))  #左上
	ft.paste(new_im_3, (xw+lineW, -lineW)) #右上
	ft.paste(new_im_2, (-lineW, xh+lineW)) #中左
	ft.paste(new_im_1, (xw+lineW, xh+lineW)) #中右
	ft.paste(new_im_3, (-lineW, xh*2+lineW*2)) #下左
	ft.paste(new_im_2, (xw+lineW, xh*2+lineW*2)) #下右
  1. 如果传入的是四张图片
    在这里插入图片描述
# 如果传入的是四张图片 
elif(num == 4):

	xw1 = int(bw*0.6)
	xh1 = int(bh*0.5)
	xw2 = int(bw*0.4)
	xh2 = int(bh*0.4)
	xh3 = int(bh*0.6)

	new_im_1 = self.resizeImage(ims[0],xw1,xh1)
	new_im_2 = self.resizeImage(ims[1],xw1,xh1)
	new_im_3 = self.resizeImage(ims[2],xw2,xh3)
	new_im_4 = self.resizeImage(ims[3],xw2,xh2)

	ft.paste(new_im_1, (-lineW, -lineW))  #左上
	ft.paste(new_im_4, (xw1+lineW, -lineW)) #右上
	ft.paste(new_im_2, (-lineW, xh1+lineW*2)) #下左
	ft.paste(new_im_3, (xw1+lineW, xh2+lineW*2)) #下右
  1. 如果传入的是五张图片
    在这里插入图片描述
# 如果传入的是5张图片
elif(num == 5):

	xw1 = int(bh*0.5)
	xh1 = int(bh*0.33333)
	xh2 = int(bh*0.5)

	new_im_1 = self.resizeImage(ims[0],xw1,xh1)
	new_im_2 = self.resizeImage(ims[1],xw1,xh1)
	new_im_3 = self.resizeImage(ims[2],xw1,xh1)
	new_im_4 = self.resizeImage(ims[3],xw1,xh2)
	new_im_5 = self.resizeImage(ims[4],xw1,xh2)

	ft.paste(new_im_1, (-lineW, -lineW))  
	ft.paste(new_im_2, (-lineW, xh1+lineW)) 
	ft.paste(new_im_3, (-lineW, (xh1+lineW)*2)) 
	ft.paste(new_im_4, (xw1+lineW, xh2+lineW)) 
	ft.paste(new_im_5, (xw1+lineW, -lineW)) 
	pass
  1. 如果传入的是六张图片
    在这里插入图片描述
# 如果传入的是6张图片
elif(num == 6):
	xw1 = int(bw*0.5)
	xh1 = int(bh*0.65)
	xw2 = int(bw*0.25)
	xh2 = int(bh*0.35)

	new_im_1 = self.resizeImage(ims[0],xw1,xh1)
	new_im_2 = self.resizeImage(ims[1],xw1,xh1)
	new_im_3 = self.resizeImage(ims[2],xw2,xh2)
	new_im_4 = self.resizeImage(ims[3],xw2,xh2)
	new_im_5 = self.resizeImage(ims[4],xw2,xh2)
	new_im_6 = self.resizeImage(ims[5],xw2,xh2)

	ft.paste(new_im_1, (-lineW, -lineW))  
	ft.paste(new_im_2, (xw1+lineW, -lineW)) 
	ft.paste(new_im_3, (-lineW*3, xh1+lineW))
	ft.paste(new_im_4, (xw2-lineW, xh1+lineW)) 
	ft.paste(new_im_5, (xw2*2+lineW, xh1+lineW)) 
	ft.paste(new_im_6, (xw2*3+lineW*3, xh1+lineW)) 
	pass
  1. 如果传入的是七张图片
    在这里插入图片描述
# 如果传入的是7张图片
elif(num == 7):
	xw1 = int(bw*0.5)
	xh1 = int(bh*0.3333)
	xw2 = bw
	xw3 = int(bw*0.25)
	
	new_im_1 = self.resizeImage(ims[0],xw1,xh1)
	new_im_2 = self.resizeImage(ims[1],xw1,xh1)
	new_im_3 = self.resizeImage(ims[2],xw2,xh1)
	new_im_4 = self.resizeImage(ims[3],xw3,xh1)
	new_im_5 = self.resizeImage(ims[4],xw3,xh1)
	new_im_6 = self.resizeImage(ims[5],xw3,xh1)
	new_im_7 = self.resizeImage(ims[6],xw3,xh1)

	ft.paste(new_im_1, (-lineW, -lineW))  
	ft.paste(new_im_2, (xw1+lineW, -lineW)) 
	ft.paste(new_im_3, (0, xh1+lineW))
	ft.paste(new_im_4, (-lineW, (xh1+lineW)*2)) 
	ft.paste(new_im_5, (xw3, (xh1+lineW)*2)) 
	ft.paste(new_im_6, (xw3*2+lineW, (xh1+lineW)*2))
	ft.paste(new_im_7, (xw3*3+lineW*2, (xh1+lineW)*2)) 
	pass
  1. 如果传入的是八张图片
    在这里插入图片描述
# 如果传入的是8张图片
elif(num == 8):
	xw1 = int(bw*0.3333)
	xh1 = int(bh*0.3333)
	xw2 = int(bw*0.6666)

	new_im_1 = self.resizeImage(ims[0],xw1,xh1)
	new_im_2 = self.resizeImage(ims[1],xw1,xh1)
	new_im_3 = self.resizeImage(ims[2],xw1,xh1)
	new_im_4 = self.resizeImage(ims[3],xw1,xh1)
	new_im_5 = self.resizeImage(ims[4],xw1,xh1)
	new_im_6 = self.resizeImage(ims[5],xw1,xh1)
	new_im_7 = self.resizeImage(ims[6],xw1,xh1)
	new_im_8 = self.resizeImage(ims[7],xw2,xh1)

	ft.paste(new_im_1, (-lineW, -lineW))  
	ft.paste(new_im_2, (xw1+lineW, -lineW)) 
	ft.paste(new_im_3, ((xw1+lineW)*2, -lineW))
	ft.paste(new_im_4, (-lineW, xh1)) 
	ft.paste(new_im_5, (xw1+lineW, xh1)) 
	ft.paste(new_im_6, ((xw1+lineW)*2, xh1))
	ft.paste(new_im_7, (-lineW, (xh1+lineW)*2))
	ft.paste(new_im_8, (xw1+lineW, (xh1+lineW)*2)) 
	pass

实现标题遮罩效果

预览

在这里插入图片描述

代码实现逻辑

def combineTextImages(self,im):

		width = im.size[0]
		height = im.size[1]
		fontSize = 60

		#生成一张空白图像
		imgCircle = Image.new("RGBA",(width,height))
		ft = ImageFont.truetype("./font/SYHT.TTF", fontSize)
		
		scale = 0.8
		img_w = int(width*scale)
		img_h = int(height*scale)
			
		# 缩放遮罩圆
		imgCircle = imgCircle.resize( (width,height) )
		draw = ImageDraw.Draw(imgCircle)
		draw.chord(( int((width-img_w)*0.5), int((height-img_h)*0.5), img_w+int((width-img_w)*0.5), img_h+int((height-img_h)*0.5) ), 0, 360, fill=(0,0,0,150))
		w = int((width-img_w)*0.5)
		h = int((height-img_h)*0.5)
		
		#绘制横条标题栏
		# imgRect = Image.new( "RGBA", (width, height) )
		# drawRect = ImageDraw.Draw(imgRect)
		txt = "水彩手绘花卉花朵植物卡片" #标题信息
		txt = txt[0:28]
		txt1 = ''
		txt2 = ''
		

		if(len(txt) > 14):
			txt1 = txt[0:13]
			txt2 = txt[13:]
		else:
			txt1 = txt

		# 如果两行
		if(txt2 != ''):
			txt1_len = self.calcTxtLen(txt1)*fontSize
			txt2_len = self.calcTxtLen(txt2)*fontSize
			draw.text( (int((width-txt1_len)/2), int(height*0.375+height*0.25*0.3)-fontSize), u''+txt1, font = ft, fill = '#ffffff') 
			draw.text( (int((width-txt2_len)/2), int(height*0.375+height*0.25*0.8)-fontSize), u''+txt2, font = ft, fill = '#ffffff') 
			pass
		# 如果一行
		else:
			txt_len = self.calcTxtLen(txt1)*fontSize
			print(txt_len)
			draw.text( (int((width-txt_len)/2), int(height*0.375+height*0.25*0.6)-fontSize), u''+txt1, font = ft, fill = '#ffffff') #int((width-txt_len)/2),int(height*0.375+height*0.25*0.4) - fontSize)
			pass

		# 开始半透明素材
		im.paste(imgCircle, ( 0, 0 ), mask=imgCircle)
		im.show()
		im.save('xxx.png')
		im.close()
		pass

根据自定义形状裁剪框合理裁剪任意大小图片逻辑

# 尺寸重新缩放
def resizeImage(self, im, w, h):
	#im = Image.open(path,"r")
	im = im
	# 获取图片尺寸
	size_w = im.size[0]
	size_h = im.size[1]

	# 判断是竖着图还是横着的图
	resize_w = 0
	resize_h = 0
	
	# 获取原素材的缩放倍数
	resize = self.calcWH(w,h,size_w,size_h)
	im = im.resize((resize[0],resize[1]))
	
	# 获取裁剪的位置x1,y1,x2,y2
	box_pos = self.calcCropPos(w,h,resize[0],resize[1])
	box = [box_pos[0],box_pos[1],box_pos[2],box_pos[3]]
	im = im.crop(box)
	
	return im


#计算宽高比例
def calcWH(self, w1, h1, w2, h2):
	
	resize_w = 0
	resize_h = 0

	# 横图
	if(w1 >= h1):
		wh_1 = h1/w1
		wh_2 = h2/w2
		# 按宽计量
		if(wh_1 < wh_2):
			resize_w = w1
			resize_h = int(w1/w2*h2)
		# 按高计量
		else:
			resize_w = int(h1/h2*w2)
			resize_h = h1
	# 竖图
	else:
		wh_1 = w1/h1
		wh_2 = w2/h2

		# 按宽计量
		if(wh_1 < wh_2):
			resize_w = int(h1/h2*w2)
			resize_h = h1
		# 按高计量
		else:
			resize_w = w1
			resize_h = int(w1/w2*h2)

	return (resize_w, resize_h)


# 计算裁剪的位置坐标
def calcCropPos(self, w1, h1, w2, h2):
	x1 = 0
	y1 = 0
	x2 = 0
	y2 = 0
	if(w1 == w1):
		x1 = 0
		y1 = int((h2-h1)*0.5)
		x2 = w1
		y2 = int((h2-h1)*0.5)+h1
	else:
		x1 = int((w2-w1)*0.5)
		y1 = 0
		x2 = int((w2-w1)*0.5)+w1
		y2 = h1
	
	return (x1, y1, x2, y2)	

猜你喜欢

转载自blog.csdn.net/WU5229485/article/details/88052932