commit a6de8ee930d620a8406e623d888eb6efdbbdda01 Author: lxb <1580622474@qq.com> Date: Sat Aug 9 16:33:50 2025 +0800 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7722683 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +inputs/ +outputs/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..0c70adf --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# 简介 +**长图拼接小工具**,可以将多个图片拼接成一个长图(竖拼),并且指定一张图始终位于中心,可以实现在缩略图的情况下看到的是中心图(如微信朋友圈)。 + +在手机相册中的效果展示: + +![](demo.gif) + +# 使用方法 +因为是临时做的小工具,没有做什么UI之类的东西,直接通过修改代码、控制台运行的方式使用。 + +可参考`app.py`中的如下代码,修改相应的输入和输出图片的名称。 +```python +input_pre_path = os.path.join(input_pre_path, '贵阳') +up_img_list = ['D.jpg', 'C.jpg', 'E.jpg', 'H.jpg', 'F.jpg'] +down_img_list = ['G.jpg', 'A.jpg', 'B.jpg'] +center_img = '中心.jpg' +output_name = '贵阳.jpg' +``` +其中`up_img_list`、`down_img_list`、`center_img`分别为上方、下方的图片列表和中心的图片名称。`output_name`为输出的图片名称。 + +另外可以修改`create_vertical_mosaic`函数的参数以修改拼接长图的宽度、背景色、图片之间的间隔像素。 +如以下例子中使用了1580的宽度、30的间隔像素,没指定背景色即采用默认的白色。 +```python +result = create_vertical_mosaic(up_img_list, down_img_list, center_img, 1580, 30) +``` + +然后用控制台执行程序即可。 +```bash +python app.py +``` + +> 注意,拼接的图片会强制将`center_img`放于中心位置,上下两侧的图片会按照顺序排列,当上下两侧的图片高度不一致的时候**会用背景色补充高度较小一侧**以确保center_img的居中。 \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..4ae113f --- /dev/null +++ b/app.py @@ -0,0 +1,96 @@ +from PIL import Image, ImageOps +import os + +input_pre_path = 'inputs' +output_pre_path = 'outputs' + +def resize_to_width(image, target_width): + w, h = image.size + ratio = target_width / w + new_height = int(h * ratio) + return image.resize((target_width, new_height)) + +def open_and_correct_image(path): + img = Image.open(path) + return ImageOps.exif_transpose(img) + +def create_vertical_mosaic(up_list_path, down_list_path, center_path, target_width = 800, interval = 10, bg_color = (255, 255, 255)): + # 加载图片 + print('加载图片...') + up_imgs = [open_and_correct_image(os.path.join(input_pre_path, p)) for p in up_list_path] + down_imgs = [open_and_correct_image(os.path.join(input_pre_path, p)) for p in down_list_path] + center_img = open_and_correct_image(os.path.join(input_pre_path, center_path)) + print('加载完成') + + # 缩放图片 + print('缩放图片...') + up_imgs = [resize_to_width(img, target_width) for img in up_imgs] + down_imgs = [resize_to_width(img, target_width) for img in down_imgs] + center_img = resize_to_width(center_img, target_width) + print('缩放完成') + + # 计算高度 + total_height = center_img.height + max(sum(img.height + interval for img in up_imgs), sum(img.height + interval for img in down_imgs)) * 2 + # 创建长图 + mosaic = Image.new('RGB', (target_width, total_height), color=bg_color) + + # 放置图片到对应位置 ----------------- + # 中心图片 + print('绘制中心...') + mosaic.paste(center_img, (0, (total_height - center_img.height) // 2)) + # 上方图片 + print('绘制上方...') + y_offset = (total_height - center_img.height) // 2 - sum(img.height + interval for img in up_imgs) + for img in up_imgs: + mosaic.paste(img, (0, y_offset)) + y_offset += img.height + interval + # 下方图片 + print('绘制下方...') + y_offset = (total_height + center_img.height) // 2 + interval + for img in down_imgs: + mosaic.paste(img, (0, y_offset)) + y_offset += img.height + interval + + # 保存 -------------------------------- + return mosaic + # output_path = os.path.join(output_pre_path, output_name) + # mosaic.save(output_path) + # print(f"保存至 {output_path}") + +# ============================================================================================================================================= + +# 贵阳 ------------------------------------------------------- +input_pre_path = os.path.join(input_pre_path, '贵阳') +up_img_list = ['D.jpg', 'C.jpg', 'E.jpg', 'H.jpg', 'F.jpg'] +down_img_list = ['G.jpg', 'A.jpg', 'B.jpg'] +center_img = '中心.jpg' +output_name = '贵阳.jpg' + +# 重庆 ------------------------------------------------------- +# input_pre_path = os.path.join(input_pre_path, '重庆') +# up_img_list = ['A2.jpg', 'J.jpg', 'D.jpg', 'C.jpg', 'E.jpg'] +# down_img_list = ['F.jpg', 'G.jpg', 'H.jpg', 'I2.jpg', 'B.jpg'] +# center_img = '中心.jpg' +# output_name = '重庆2.jpg' + +# 洛阳 ------------------------------------------------------- +# input_pre_path = os.path.join(input_pre_path, '洛阳') +# up_img_list = ['A.jpg', 'D.jpg', 'C.jpg', 'G.jpg'] +# down_img_list = ['F.jpg', 'E.jpg', 'H2.jpg', 'B.jpg', 'I.jpg'] +# center_img = '中心.jpg' +# output_name = '洛阳2.jpg' + +# 上海 ------------------------------------------------------- +# input_pre_path = os.path.join(input_pre_path, '上海') +# up_img_list = ['G.jpg', 'J.jpg', 'D.jpg', 'E.jpg', 'C.jpg', 'A.jpg'] +# down_img_list = ['B.jpg', 'F.jpg', 'H.jpg', 'I.jpg'] +# center_img = '中心.jpg' +# output_name = '上海.jpg' + +print('开始处理...') +result = create_vertical_mosaic(up_img_list, down_img_list, center_img, 1580, 30) +output_path = os.path.join(output_pre_path, output_name) +result.save(output_path) +print(f"保存至 {output_path}") + +print('处理结束') diff --git a/demo.gif b/demo.gif new file mode 100644 index 0000000..81c7398 Binary files /dev/null and b/demo.gif differ