Skip to content

Commit afff451

Browse files
authored
Add files via upload
1 parent f041051 commit afff451

File tree

2 files changed

+214
-0
lines changed

2 files changed

+214
-0
lines changed

image_grid.py

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import os
2+
import PIL
3+
import random
4+
# from PIL import Image, ImageOps
5+
import PIL.Image
6+
import PIL.ImageOps
7+
from tkinter import filedialog
8+
from tkinter import *
9+
root = Tk()
10+
root.withdraw()
11+
folder_selected = filedialog.askdirectory()
12+
# print(folder_selected)
13+
# Get list of image paths
14+
image_paths_list = [os.path.join(folder_selected, f) for f in os.listdir(folder_selected) if f.endswith('.png')]
15+
16+
# print(image_paths_list)
17+
18+
# image_paths_list.sort
19+
20+
# print(image_paths_list)
21+
22+
23+
def concat_images(size, shape=None):
24+
25+
# Open images and resize them
26+
images = map(PIL.Image.open, image_paths_list)
27+
28+
images = [PIL.ImageOps.fit(img, size) for img in images]
29+
# print('number', len(images))
30+
image_count = len(image_paths_list)
31+
print(image_count)
32+
width, height = size
33+
34+
# Create canvas for the final image with total size
35+
shape_list = shape if shape else (1, len(images))
36+
image_size = (width * shape_list[0], height * shape_list[1])
37+
final_image = PIL.Image.new('RGB', image_size)
38+
39+
# Paste images into final image
40+
for col in range(shape_list[0]):
41+
for row in range(shape_list[1]):
42+
offset = (width * col, height * row)
43+
# idx = row * shape_list[1] + col ---WRONG!
44+
idx = row + col * shape_list[1]
45+
if idx == image_count:
46+
return final_image
47+
final_image.paste(images[idx], offset)
48+
49+
return final_image
50+
51+
52+
# Create and save image grid
53+
image = concat_images(size=(421, 750), shape=(9, 4)) # width x height
54+
image.save('image' + str(random.randint(0, 100000000)) + '.png', 'PNG')
55+
56+
57+
# image = concat_images((800, 800), (3, 3)) # width x height

image_pair.py

+157
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
from PIL import Image
2+
# Open image using Image module
3+
4+
import tkinter as tk
5+
from tkinter import filedialog
6+
7+
# 1600 = hd (high definition, for social media)
8+
# 1920 x 1280 = fhd (full hd)
9+
# 2560 x 1440 = qhd (quad hd, aka 2k)
10+
# 3840 x 2160 = 4k
11+
# 7680 x 4320 = 8k
12+
res_str = "4k"
13+
14+
res_str_list = ["hd", "fhd", "qhd", "4k", "8k", "10k", "12k", "14k", "max"]
15+
res_list = [1600, 1920, 2560, 3840, 7680, 10000, 12000, 14000, 99999]
16+
max_final_image_dimension = res_list[res_str_list.index(res_str)]
17+
18+
crop_shift = 283 # pixels to remove from one side of each image. The side affected depends on pairing orientation.
19+
image_merge = 1 # either merge the images to one, or save them separately, just resized
20+
if not image_merge:
21+
crop_shift = 0
22+
23+
save = 1 # if save is off, just display the image for a review
24+
show = 1 # only show final image(s) if this is on of if it is not saving
25+
image_rotate = 0 # value here is number of quarter turns (range of integers 1-3, or 0 for off).
26+
# Note that the flips occur after the rotation
27+
A_flip_H = 0
28+
A_flip_V = 0
29+
B_flip_H = 0
30+
B_flip_V = 0
31+
A_first_override = 0
32+
orientation_override = 0 # 1 for horizontal arrangement, -1 for vertical. 0 for automatic.
33+
duplicated = 0 # set to 1 to duplicate a single image
34+
35+
root = tk.Tk()
36+
root.withdraw()
37+
38+
image_name = filedialog.askopenfilename(title='select', filetypes=[("image", ".png"), ("image", ".jpg")])
39+
base_image_extension = image_name[-4:len(image_name)]
40+
41+
if duplicated:
42+
image_name_A = image_name
43+
image_name_B = image_name
44+
duplicated = image_merge
45+
elif image_name[-5] == "B":
46+
A_first = 0 if not A_first_override else 1
47+
image_name_B = image_name
48+
base_image_name = image_name[0:(len(image_name) - 6)]
49+
image_name_A = base_image_name + base_image_extension
50+
else:
51+
A_first = 1
52+
image_name_A = image_name
53+
base_image_name = image_name[0:(len(image_name) - 4)]
54+
image_name_B = base_image_name + "-B" + base_image_extension
55+
56+
image_A = Image.open(image_name_A)
57+
image_B = Image.open(image_name_B)
58+
if image_rotate == 1:
59+
image_A = image_A.transpose(Image.Transpose.ROTATE_90)
60+
image_B = image_B.transpose(Image.Transpose.ROTATE_90)
61+
elif image_rotate == 2:
62+
image_A = image_A.transpose(Image.Transpose.ROTATE_180)
63+
image_B = image_B.transpose(Image.Transpose.ROTATE_180)
64+
elif image_rotate == 3:
65+
image_A = image_A.transpose(Image.Transpose.ROTATE_270)
66+
image_B = image_B.transpose(Image.Transpose.ROTATE_270)
67+
if A_flip_H:
68+
image_A = image_A.transpose(Image.Transpose.FLIP_LEFT_RIGHT)
69+
if A_flip_V:
70+
image_A = image_A.transpose(Image.Transpose.FLIP_TOP_BOTTOM)
71+
if B_flip_H:
72+
image_B = image_B.transpose(Image.Transpose.FLIP_LEFT_RIGHT)
73+
if B_flip_V:
74+
image_B = image_B.transpose(Image.Transpose.FLIP_TOP_BOTTOM)
75+
76+
width, height = image_A.size
77+
AR = height/width
78+
print(f"starting image dimensions = {width} x {height}, AR = {round(height/width, 3)}")
79+
80+
X_pair = False
81+
Y_pair = False
82+
if image_merge:
83+
if (height / width >= 1.125 or orientation_override == 1) and not orientation_override == -1:
84+
# if it's a taller image, set up side by side.
85+
# But if closer to square, keep vertical arrangement
86+
max_image_dim = max(2 * (width - crop_shift), height)
87+
X_pair = True
88+
else:
89+
max_image_dim = max(2 * (height - crop_shift), width)
90+
Y_pair = True
91+
else:
92+
max_image_dim = max(width, height)
93+
94+
crop_X = crop_shift if X_pair else 0
95+
crop_Y = crop_shift if Y_pair else 0
96+
97+
scale_factor = max_final_image_dimension / max_image_dim
98+
99+
if duplicated:
100+
image1 = image_A
101+
image2 = image_B
102+
suffix_abba = "DD"
103+
elif A_first:
104+
image1 = image_A
105+
image2 = image_B
106+
suffix_abba = "-AB"
107+
else:
108+
image1 = image_B
109+
image2 = image_A
110+
suffix_abba = "-BA"
111+
112+
if crop_shift > 0:
113+
left = 0
114+
top = 0
115+
right = width - left - crop_X
116+
bottom = height - crop_Y
117+
118+
image1 = image1.crop((left, top, right, bottom))
119+
image2 = image2.crop((left + crop_X, top + crop_Y, width - left, height))
120+
width, height = image1.size
121+
print(f"cropped image dimensions = {width} x {height}")
122+
123+
if scale_factor < 1.0:
124+
image1R = image1.resize((round(width * scale_factor), round(height * scale_factor)))
125+
image2R = image2.resize((round(width * scale_factor), round(height * scale_factor)))
126+
width, height = image1R.size
127+
print(f"resized image dimensions = {width} x {height}")
128+
else:
129+
image1R = image1
130+
image2R = image2
131+
print(f"desired size exceeds image dimensions, no resize necessary.")
132+
res_str = "max"
133+
134+
if image_merge:
135+
if X_pair:
136+
new_image = Image.new('RGB', (2 * image1R.size[0], image1R.size[1]), (250, 250, 250))
137+
new_image.paste(image1R, (0, 0))
138+
new_image.paste(image2R, (image2R.size[0], 0))
139+
else:
140+
new_image = Image.new('RGB', (image1R.size[0], 2 * image1R.size[1]), (250, 250, 250))
141+
new_image.paste(image1R, (0, 0))
142+
new_image.paste(image2R, (0, image2R.size[1]))
143+
144+
width, height = new_image.size
145+
print(f"merged image dimensions = {width} x {height}, AR = {round(height/width, 3)}")
146+
if save:
147+
new_image.save(base_image_name + suffix_abba + "-" + res_str + ".png", "PNG")
148+
if show or not save:
149+
new_image.show()
150+
else:
151+
if save:
152+
image1R.save(base_image_name + "-A-" + res_str + ".png", "PNG")
153+
image2R.save(base_image_name + "-B-" + res_str + ".png", "PNG")
154+
else:
155+
image1R.show()
156+
image2R.show()
157+
# ---------------------------------------------------------------

0 commit comments

Comments
 (0)