Spaces:
Running
Running
Upload app.py
Browse files
app.py
CHANGED
|
@@ -57,19 +57,33 @@ def concatenate_images(images, direction="horizontal", spacing=0, background_col
|
|
| 57 |
if not valid_images:
|
| 58 |
return None
|
| 59 |
|
| 60 |
-
|
| 61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
|
| 63 |
if direction == "horizontal":
|
| 64 |
# 水平拼接
|
| 65 |
-
total_width = sum(img.size[0] for img in
|
| 66 |
-
max_height = max(img.size[1] for img in
|
| 67 |
|
| 68 |
-
# 創建新圖片
|
| 69 |
result = Image.new('RGB', (total_width, max_height), background_color)
|
| 70 |
|
| 71 |
x_offset = 0
|
| 72 |
-
for img in
|
| 73 |
# 垂直居中放置
|
| 74 |
y_offset = (max_height - img.size[1]) // 2
|
| 75 |
result.paste(img, (x_offset, y_offset))
|
|
@@ -77,14 +91,14 @@ def concatenate_images(images, direction="horizontal", spacing=0, background_col
|
|
| 77 |
|
| 78 |
else: # vertical
|
| 79 |
# 垂直拼接
|
| 80 |
-
max_width = max(img.size[0] for img in
|
| 81 |
-
total_height = sum(img.size[1] for img in
|
| 82 |
|
| 83 |
-
# 創建新圖片
|
| 84 |
result = Image.new('RGB', (max_width, total_height), background_color)
|
| 85 |
|
| 86 |
y_offset = 0
|
| 87 |
-
for img in
|
| 88 |
# 水平居中放置
|
| 89 |
x_offset = (max_width - img.size[0]) // 2
|
| 90 |
result.paste(img, (x_offset, y_offset))
|
|
@@ -92,8 +106,33 @@ def concatenate_images(images, direction="horizontal", spacing=0, background_col
|
|
| 92 |
|
| 93 |
return result
|
| 94 |
|
| 95 |
-
def
|
| 96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
"""
|
| 98 |
處理圖片拼接的主函數
|
| 99 |
"""
|
|
|
|
| 57 |
if not valid_images:
|
| 58 |
return None
|
| 59 |
|
| 60 |
+
# 確保所有圖片都轉換為RGB模式(去除透明通道)
|
| 61 |
+
rgb_images = []
|
| 62 |
+
for img in valid_images:
|
| 63 |
+
if img.mode != 'RGB':
|
| 64 |
+
# 如果有透明通道,先貼到白色背景上
|
| 65 |
+
if img.mode in ('RGBA', 'LA'):
|
| 66 |
+
background = Image.new('RGB', img.size, 'white')
|
| 67 |
+
background.paste(img, mask=img.split()[-1] if img.mode == 'RGBA' else None)
|
| 68 |
+
rgb_images.append(background)
|
| 69 |
+
else:
|
| 70 |
+
rgb_images.append(img.convert('RGB'))
|
| 71 |
+
else:
|
| 72 |
+
rgb_images.append(img)
|
| 73 |
+
|
| 74 |
+
if len(rgb_images) == 1:
|
| 75 |
+
return rgb_images[0]
|
| 76 |
|
| 77 |
if direction == "horizontal":
|
| 78 |
# 水平拼接
|
| 79 |
+
total_width = sum(img.size[0] for img in rgb_images) + spacing * (len(rgb_images) - 1)
|
| 80 |
+
max_height = max(img.size[1] for img in rgb_images)
|
| 81 |
|
| 82 |
+
# 創建新圖片 - 確保為RGB模式
|
| 83 |
result = Image.new('RGB', (total_width, max_height), background_color)
|
| 84 |
|
| 85 |
x_offset = 0
|
| 86 |
+
for img in rgb_images:
|
| 87 |
# 垂直居中放置
|
| 88 |
y_offset = (max_height - img.size[1]) // 2
|
| 89 |
result.paste(img, (x_offset, y_offset))
|
|
|
|
| 91 |
|
| 92 |
else: # vertical
|
| 93 |
# 垂直拼接
|
| 94 |
+
max_width = max(img.size[0] for img in rgb_images)
|
| 95 |
+
total_height = sum(img.size[1] for img in rgb_images) + spacing * (len(rgb_images) - 1)
|
| 96 |
|
| 97 |
+
# 創建新圖片 - 確保為RGB模式
|
| 98 |
result = Image.new('RGB', (max_width, total_height), background_color)
|
| 99 |
|
| 100 |
y_offset = 0
|
| 101 |
+
for img in rgb_images:
|
| 102 |
# 水平居中放置
|
| 103 |
x_offset = (max_width - img.size[0]) // 2
|
| 104 |
result.paste(img, (x_offset, y_offset))
|
|
|
|
| 106 |
|
| 107 |
return result
|
| 108 |
|
| 109 |
+
def save_as_jpg(image, quality=95):
|
| 110 |
+
"""
|
| 111 |
+
將圖片保存為高質量JPG格式
|
| 112 |
+
"""
|
| 113 |
+
if image is None:
|
| 114 |
+
return None
|
| 115 |
+
|
| 116 |
+
# 確保圖片為RGB模式
|
| 117 |
+
if image.mode != 'RGB':
|
| 118 |
+
if image.mode in ('RGBA', 'LA'):
|
| 119 |
+
# 有透明通道的圖片,貼到白色背景上
|
| 120 |
+
background = Image.new('RGB', image.size, 'white')
|
| 121 |
+
if image.mode == 'RGBA':
|
| 122 |
+
background.paste(image, mask=image.split()[-1])
|
| 123 |
+
else:
|
| 124 |
+
background.paste(image, mask=image.split()[-1])
|
| 125 |
+
image = background
|
| 126 |
+
else:
|
| 127 |
+
image = image.convert('RGB')
|
| 128 |
+
|
| 129 |
+
# 保存到bytes buffer
|
| 130 |
+
buffer = io.BytesIO()
|
| 131 |
+
image.save(buffer, format='JPEG', quality=quality, optimize=True)
|
| 132 |
+
buffer.seek(0)
|
| 133 |
+
|
| 134 |
+
# 重新加載為PIL圖片
|
| 135 |
+
return Image.open(buffer)
|
| 136 |
"""
|
| 137 |
處理圖片拼接的主函數
|
| 138 |
"""
|