|
from PIL import Image |
|
from typing import List |
|
|
|
|
|
def create_image_grid(image_paths: List[str], output_path: str, grid_size: int = 2) -> None: |
|
""" |
|
将多个图片合并为 4 宫格图片,少于 4 个则留空,确保透明背景被填充为白色,并实现等比缩放。 |
|
|
|
参数: |
|
- image_paths: 输入图片路径列表 |
|
- output_path: 输出 4 宫格图片路径 |
|
- grid_size: 网格大小(默认 2x2) |
|
""" |
|
images = [] |
|
target_size = (256, 256) |
|
|
|
for path in image_paths[:4]: |
|
try: |
|
|
|
img = Image.open(path).convert('RGBA') |
|
|
|
|
|
if img.mode == 'RGBA': |
|
background = Image.new('RGBA', img.size, (255, 255, 255, 255)) |
|
img = Image.alpha_composite(background, img) |
|
|
|
|
|
img = img.convert('RGB') |
|
original_width, original_height = img.size |
|
aspect_ratio = original_width / original_height |
|
if original_width >= original_height: |
|
|
|
new_width = 256 |
|
new_height = int(256 / aspect_ratio) |
|
else: |
|
|
|
new_height = 256 |
|
new_width = int(256 * aspect_ratio) |
|
|
|
|
|
img = img.resize((new_width, new_height), Image.Resampling.LANCZOS) |
|
|
|
|
|
|
|
canvas = Image.new('RGB', target_size, (255, 255, 255)) |
|
|
|
|
|
offset_x = (target_size[0] - img.size[0]) // 2 |
|
offset_y = (target_size[1] - img.size[1]) // 2 |
|
|
|
|
|
canvas.paste(img, (offset_x, offset_y)) |
|
|
|
images.append(canvas) |
|
except Exception as e: |
|
print(f"Error loading image {path}: {e}") |
|
images.append(None) |
|
|
|
|
|
while len(images) < 4: |
|
images.append(None) |
|
|
|
|
|
grid_image = Image.new('RGB', (512, 512), (255, 255, 255)) |
|
|
|
|
|
for idx, img in enumerate(images): |
|
if img is not None: |
|
x = (idx % 2) * 256 |
|
y = (idx // 2) * 256 |
|
grid_image.paste(img, (x, y)) |
|
|
|
|
|
grid_image.save(output_path, quality=95) |
|
|