Python PIL实现带缩放的模糊背景图叠加结果不符合预期
问题根因
原有代码的模糊背景生成逻辑错误:直接将原图强制拉伸为1080*1080尺寸,没有采用等比放大后居中裁切的cover缩放模式,同时高斯模糊半径参数和工具设置不匹配,最终效果和预期存在明显差异。
正确实现逻辑
要还原对应模糊边框效果,按以下步骤处理即可:
- 先对去边框后的原图做等比cover缩放:计算缩放比例时取「画布宽度/原图宽度」「画布高度/原图高度」两个值的较大值,保证缩放后图片完全覆盖1080*1080画布,不会留黑边也不会拉伸变形
- 将缩放后的图片居中裁切,取出中间1080*1080的区域作为模糊底图的基础
- 对裁切好的底图应用半径为30的高斯模糊(匹配工具对应参数的模糊强度)
- 将上层原图等比缩放到宽度1080px,居中叠加到模糊背景上,导出最终结果
修改后完整代码
from PIL import Image, ImageFilter, ImageChops import numpy import cv2 def remove_border(file_img): im = Image.open(file_img) bg = Image.new("RGB", im.size, im.getpixel((0,0))) diff = ImageChops.difference(im.convert("RGB"), bg) diff = ImageChops.add(diff, diff, 2.0, -30) bbox = diff.getbbox() if bbox: return im.crop(bbox) return im def resize_blur(img_blur, target_size): target_w, target_h = target_size origin_w, origin_h = img_blur.size # 计算cover模式缩放比例,取宽高缩放比的较大值,实现zoom放大效果 scale = max(target_w / origin_w, target_h / origin_h) new_w = int(origin_w * scale) new_h = int(origin_h * scale) # 等比缩放,无拉伸 img_blur = img_blur.resize((new_w, new_h), resample=Image.Resampling.LANCZOS) # 居中裁切出目标尺寸区域 left = (new_w - target_w) // 2 top = (new_h - target_h) // 2 right = left + target_w bottom = top + target_h img_blur = img_blur.crop((left, top, right, bottom)) # 应用匹配工具参数的高斯模糊 img_blur = img_blur.filter(ImageFilter.GaussianBlur(radius=30)) return img_blur def resize_width_main(img_border,size_width): basewidth = size_width wpercent = (basewidth/float(img_border.size[0])) hsize = int((float(img_border.size[1])*float(wpercent))) img_width = img_border.resize((basewidth,hsize), Image.Resampling.LANCZOS) return img_width def center_overlay(name_file,overlay,background): img = numpy.asarray(overlay) img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) h, w = img.shape[:2] back = numpy.asarray(background) back = cv2.cvtColor(back, cv2.COLOR_RGB2BGR) hh, ww = back.shape[:2] yoff = round((hh-h)/2) xoff = round((ww-w)/2) result = back.copy() result[yoff:yoff+h, xoff:xoff+w] = img cv2.imwrite(name_file, result) def main(): img_border = remove_border('resized_download.png') # 生成1080*1080的zoom效果模糊背景 img_blur = resize_blur(img_border, (1080,1080)) # 上层原图等比缩放到宽度1080px img_width = resize_width_main(img_border, 1080) center_overlay('resized.png', img_width, img_blur) if __name__ == '__main__': main()
参数调整说明
- 如果需要调整模糊强度,直接修改
GaussianBlur的radius参数即可,数值越大模糊效果越强 - 缩放统一使用LANCZOS采样,保证输出画质最高
- 代码中保留了原有的自动去白边逻辑,如果不需要可以直接注释掉
remove_border相关调用,直接读取原图处理即可
内容的提问来源于stack exchange,提问作者Digital Farmer
相关产品推荐
相关产品推荐

