1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| def xywh2xyxyxyxy(x,y,w,h): return [[x,y],[x+w,y],[x+w,y+h],[x,y+h]]
def merge_image(fore_image, back_image, pos=(0,0),alpha=1.0,factor=1.0,padding=False,func=lambda x:x): """将两个图片进行合并,支持自定义透明度 alpha, 缩放factor, 背景图缩放开关 padding, 前景图回调函数 func
Args: fore_image (PIL.Image): 前景图 back_image (PIL.Image): 背景图 pos (tuple, list): 左上角位置. Defaults to (0,0). alpha (float, optional): 前景透明度. Defaults to 1.0. factor (float, optional): 前景缩放因子. Defaults to 1.0. padding (bool, optional): 背景自适应缩放. Defaults to False. func (Functional, optional): 前景处理回调函数. Defaults to lambdax:x.
Returns: PIL.Image: 合并后的图片 """ assert alpha <= 1.0, "Alpha must be less or equel than 1.0" final_image = back_image.copy() fore_image_temp = fore_image.copy() # 设置缩放因子 透明度 fore_h, fore_w = fore_image_temp.size print(fore_w,fore_h) fore_new_w = int(fore_w / factor) fore_new_h = int(fore_h / factor) for i in range(fore_new_w): for k in range(fore_new_h): color = fore_image_temp.getpixel((i, k)) color = color[:-1] + (int((color[-1]*alpha)%255), ) fore_image_temp.putpixel((i, k), color) fore_image_temp = fore_image_temp.resize((fore_new_w, fore_new_h), Image.Resampling.LANCZOS) fore_image_temp = func(fore_image_temp)
# 背景图不够大将会被resize if padding: back_limit_w = fore_new_w + pos[0] back_limit_h = fore_new_h + pos[1] else: back_limit_w = fore_new_w back_limit_h = fore_new_h # 设置背景图片大小 back_h,back_w = final_image.size # 设置背景图大小 if back_w < back_limit_w: back_new_w = back_limit_w print(f"背景图宽度过小, {back_w} < {back_limit_w}") if back_h < back_limit_h: back_new_h = back_limit_h print(f"背景图高度过小, {back_h} < {back_limit_h}") final_image = final_image.resize((back_new_w,back_new_h),Image.Resampling.LANCZOS) final_image.paste(fore_image_temp, pos, mask=fore_image_temp) fore_final_h, fore_final_w = fore_image_temp.size back_final_h, back_final_w =final_image.size label_x = pos[0] if pos[0]>0 else 0 label_y = pos[1] if pos[1]>0 else 0 label_w = pos[0]+fore_final_w-label_x if pos[0]+fore_final_w < back_final_w else back_final_w-label_x label_h = pos[1]+fore_final_h-label_y if pos[1]+fore_final_h < back_final_h else back_final_h-label_y return final_image, xywh2xyxyxyxy(label_x,label_y,label_w,label_h)
|