如需转载,请注明出处。
更多优质内容,详细测试程序,可点击原文链接进行阅读学习。
合并前景与背景两张图片,可设置图片前景的透明度,缩放因子,位置,可自适应调整背景大小并且输出图片所在边界框位置,用于标注数据
paste
alpha
值,对图片透明度进行修改2022.11.25 修复长宽相反的问题
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)