Python代码
from PIL import Image
import os # 导入os模块,用于文件和目录操作
def get_image_paths_from_folder(folder_path, extensions=('.png', '.jpg', '.jpeg', '.gif', '.bmp')):
"""
从指定文件夹中获取所有指定扩展名的图片文件路径。
Args:
folder_path (str): 图片所在的文件夹路径。
extensions (tuple): 包含图片文件扩展名的元组,默认为常见图片格式。
Returns:
list: 包含所有图片文件完整路径的列表。
"""
image_paths = []
if not os.path.exists(folder_path): # 检查文件夹是否存在
print(f"错误: 文件夹 '{folder_path}' 不存在。")
return image_paths
for filename in os.listdir(folder_path): # 遍历文件夹中的所有文件和子文件夹
if filename.lower().endswith(extensions): # 检查文件是否为图片(大小写不敏感)
full_path = os.path.join(folder_path, filename) # 拼接完整文件路径
if os.path.isfile(full_path): # 再次确认是文件而不是子文件夹
image_paths.append(full_path)
image_paths.sort() # 为了保证拼接顺序,可以根据文件名排序
return image_paths
def stitch_and_compress_images(image_paths, output_path, quality=85):
"""
将多张长宽相同的图片横向拼接成一张图,并对结果图进行压缩。
(此函数与之前基本相同,但为完整性再次包含)
Args:
image_paths (list): 包含所有待拼接图片文件路径的列表。
output_path (str): 拼接完成后图片的保存路径。
quality (int, optional): 压缩质量,范围0-95,越高图片质量越好,文件越大。
默认为85,适用于JPEG格式。
"""
if not image_paths:
print("图片路径列表不能为空,无法进行拼接!")
return
# 尝试打开第一张图片以获取基准尺寸
try:
first_image = Image.open(image_paths[0])
width, height = first_image.size
except FileNotFoundError:
print(f"错误: 找不到第一张图片 {image_paths[0]},无法获取基准尺寸。")
return
except Exception as e:
print(f"打开第一张图片 {image_paths[0]} 时发生错误: {e}")
return
finally:
first_image.close() # 立即关闭第一张图片,避免长时间占用
# 过滤掉尺寸不匹配的图片,并重新构建一个有效图片路径列表
valid_image_paths = []
print(f"基准图片尺寸: ({width}, {height})")
for path in image_paths:
try:
with Image.open(path) as img: # 使用with语句确保图片自动关闭
if img.size == (width, height):
valid_image_paths.append(path)
else:
print(f"警告: 图片 '{os.path.basename(path)}' 的尺寸 ({img.size}) 与基准尺寸不符,已跳过。")
except FileNotFoundError:
print(f"错误: 找不到文件 '{os.path.basename(path)}',已跳过。")
except Exception as e:
print(f"处理图片 '{os.path.basename(path)}' 时发生错误: {e},已跳过。")
if not valid_image_paths:
print("没有找到符合尺寸要求的图片,无法进行拼接!")
return
# 计算拼接后图片的宽度
total_width = width * len(valid_image_paths)
# 创建一张新的空白图片,用于存放拼接后的内容
new_image = Image.new('RGB', (total_width, height))
x_offset = 0 # 记录当前图片粘贴的起始X坐标
for path in valid_image_paths: # 遍历有效图片路径列表
try:
with Image.open(path) as img: # 使用with语句确保图片自动关闭
# 将当前图片粘贴到新图片上
new_image.paste(img, (x_offset, 0))
x_offset += width # 更新下一个图片粘贴的X坐标
except Exception as e:
print(f"粘贴图片 '{os.path.basename(path)}' 时发生错误: {e},已跳过。")
# 保存拼接后的图片并进行压缩
try:
new_image.save(output_path, quality=quality, optimize=True)
print(f"图片拼接与压缩完成,保存至: {output_path}")
except Exception as e:
print(f"保存或压缩图片时发生错误: {e}")
finally:
new_image.close() # 关闭新创建的图片
# 示例使用
if __name__ == "__main__":
# 1. 创建一个用于存放示例图片的文件夹
input_folder = '2'
os.makedirs(input_folder, exist_ok=True) # 如果文件夹不存在则创建
# 2. 创建一些示例图片放入该文件夹
try:
# 尺寸相同的图片
img1 = Image.new('RGB', (100, 50), color = 'red')
img1.save(os.path.join(input_folder, 'image1.png'))
img2 = Image.new('RGB', (100, 50), color = 'green')
img2.save(os.path.join(input_folder, 'image2.jpg'))
img3 = Image.new('RGB', (100, 50), color = 'blue')
img3.save(os.path.join(input_folder, 'image3.png'))
# 一张尺寸不同的图片,用于测试过滤功能
img_diff_size = Image.new('RGB', (50, 50), color = 'yellow')
img_diff_size.save(os.path.join(input_folder, 'diff_size_image.png'))
# 一张非图片文件,确保不会被误读
with open(os.path.join(input_folder, 'not_an_image.txt'), 'w') as f:
f.write("This is not an image.")
print(f"示例图片已创建在 '{input_folder}' 文件夹中。")
except ImportError:
print("Pillow 库未安装。请使用 'pip install Pillow' 安装。")
exit()
# 3. 设置输出文件路径
output_merged_file = 'output.jpg'
print("\n--- 开始处理 ---")
# 4. 获取文件夹中的图片路径
all_image_paths = get_image_paths_from_folder(input_folder)
# 5. 调用拼接和压缩函数
stitch_and_compress_images(all_image_paths, output_merged_file, quality=75)
print("\n--- 任务完成 ---")
# 清理示例图片 (可选)
# import shutil
# shutil.rmtree(input_folder)
# print(f"清理了示例文件夹 '{input_folder}'。")主要功能和解释
这个脚本用于从指定文件夹读取图片(按文件名排序、只取指定扩展名),把尺寸相同的多张图片按水平方向拼接成一张大图并保存,同时对结果进行压缩(主要用于 JPEG)。
使用注意
- 只会拼接与第一张图片尺寸完全相同的图片;若要包含不同尺寸可以先统一缩放/裁剪。
- quality 参数对 JPEG 有效;如果输出 PNG,可使用 optimize=True 和 ompress_level 参数(Pillow 支持)。
- 大量或超长图片拼接可能占用大量内存,需谨慎(可考虑按块处理或增加临时磁盘缓存)。
- 如果需要保留透明通道,创建新图时应使用模式 ‘RGBA’ 并保存为 PNG。