Repository navigation
Expand file tree
/
Copy pathGridMerge94.py
More file actions
166 lines (145 loc) · 6.77 KB
/
Copy pathGridMerge94.py
File metadata and controls
166 lines (145 loc) · 6.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
from PIL import Image,ImageFile
import os
from tqdm import tqdm
import shutil
import sys
import re
ImageFile.LOAD_TRUNCATED_IMAGES = True
Image.MAX_IMAGE_PIXELS = None
def get_image_ratio(image_path):
try:
with Image.open(image_path) as img:
width, height = img.size
ratio = width / height
orientation = "horizontal" if width >= height else "vertical"
return ratio, orientation, width, height
except Exception as e:
print(f"Error processing image {image_path}: {e}")
return None, None, None, None
def resize_image(image_path, target_size):
try:
with Image.open(image_path) as img:
resized_img = img.resize(target_size, Image.LANCZOS)
return resized_img
except Exception as e:
print(f"Error resizing image {image_path}: {e}")
return None
def group_images_by_ratio_and_size(directory):
image_files = [f for f in os.listdir(directory) if not f.startswith('.') and f.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp'))]
image_files.sort()
grouped_images = {"16:9": [], "4:3": [], "3:4": [], "9:16": [], "2:3": [], "3:2": [], "horizontal": [], "vertical": []}
if not image_files:
return grouped_images
for image_file in image_files:
image_path = os.path.join(directory, image_file)
ratio, orientation, width, height = get_image_ratio(image_path)
if ratio is not None and orientation is not None:
if 1.7 < ratio < 1.81:
target_size = (4800, 2700)
whname = "16:9"
elif 1.3 < ratio < 1.41:
target_size = (4800, 3600)
whname = "4:3"
elif 0.7 < ratio < 0.81:
target_size = (3600, 4800)
whname = "3:4"
elif 0.5 < ratio < 0.61:
target_size = (2700, 4800)
whname = "9:16"
elif 0.65 < ratio < 0.67: # Adjusted for 2:3 aspect ratio
target_size = (3200, 4800)
whname = "2:3"
elif 1.48 < ratio < 1.52: # Adjusted for 3:2 aspect ratio
target_size = (4800, 3200)
whname = "3:2"
else:
whname = orientation
# 等比例缩放,保持高度为4800
target_size = (int(4800 * (width/height)), 4800)
# continue
grouped_images[whname].append((image_path, target_size))
return grouped_images
def create_collage(images, output_directory, base_name, layout):
try:
resized_images = [(resize_image(image_path, target_size), target_size) for image_path, target_size in images if resize_image(image_path, target_size) is not None]
total_images = len(resized_images)
# progress_bar = tqdm(total=total_images, desc=f"Creating {layout} collage")
if layout == "3x3":
width, height = resized_images[0][0].size
total_width = 3 * width
total_height = 3 * height
collage = Image.new('RGB', (total_width, total_height))
for i in range(3):
for j in range(3):
index = i * 3 + j
if index < total_images:
collage.paste(resized_images[index][0], (j * width, i * height))
# progress_bar.update(1)
elif layout == "2x2":
width, height = resized_images[0][0].size
total_width = 2 * width
total_height = 2 * height
collage = Image.new('RGB', (total_width, total_height))
for i in range(2):
for j in range(2):
index = i * 2 + j
if index < total_images:
collage.paste(resized_images[index][0], (j * width, i * height))
# progress_bar.update(1)
elif layout == "1xM":
total_width = sum(image[0].size[0] for image in resized_images)
total_height = resized_images[0][0].size[1]
collage = Image.new('RGB', (total_width, total_height))
current_width = 0
for image, filename in resized_images:
collage.paste(image, (current_width, 0))
current_width += image.width # 更新当前宽度
# progress_bar.close()
# Ensure the output directory exists
os.makedirs(output_directory, exist_ok=True)
# Save the collage with a numbered filename
safe_base_name = re.sub(r'[\/:*?"<>|]', '', base_name)
output_path = os.path.join(output_directory, f'{safe_base_name}_{len(os.listdir(output_directory)) + 1}.jpg')
collage.save(output_path)
except Exception as e:
print(f"Error creating collage: {e}")
def copy_images(images, output_directory, base_name):
try:
for i, (image_path, target_size) in enumerate(images):
resized_img = resize_image(image_path, target_size)
output_path = os.path.join(output_directory, f'{base_name}_{i + 1}.jpg')
if resized_img is not None:
resized_img.save(output_path)
except Exception as e:
print(f"Error copying images: {e}")
def process_directory(directory):
grouped_images = group_images_by_ratio_and_size(directory)
for orientation, images in grouped_images.items():
if images == []:
continue
directory_progress_bar = tqdm(total=len(images), desc="Processing", position=0)
orientation = orientation.replace(":", "x")
directory_progress_bar.set_postfix({"CD": os.path.basename(directory), "OR": orientation})
batches_3x3 = [images[i:i+9] for i in range(0, len(images) // 9 * 9, 9)]
remaining_images = len(images) - len(batches_3x3) * 9
batches_2x2 = [images[i:i+4] for i in range(len(batches_3x3) * 9, len(batches_3x3) * 9 + (remaining_images // 4) * 4, 4)]
batch_1xM = images[len(batches_3x3) * 9 + len(batches_2x2) * 4:]
for batch in batches_3x3:
create_collage(batch, directory, f"{os.path.basename(directory)}_{orientation}", "3x3")
directory_progress_bar.update(9)
for batch in batches_2x2:
create_collage(batch, directory, f"{os.path.basename(directory)}_{orientation}", "2x2")
directory_progress_bar.update(4)
if not len(batch_1xM)==0:
create_collage(batch_1xM, directory, f"{os.path.basename(directory)}_{orientation}", "1xM")
directory_progress_bar.update(len(batch_1xM))
directory_progress_bar.close()
def main():
if len(sys.argv) != 2:
print("Usage: python script.py <root_directory>")
sys.exit(1)
root_directory = sys.argv[1]
for current_directory, _, _ in os.walk(root_directory):
process_directory(current_directory)
if __name__ == "__main__":
main()