Last active
March 29, 2023 19:39
-
-
Save tjibbevanderlaan/00a662f8fc8341d8e3e99314a5cd5fae to your computer and use it in GitHub Desktop.
Create collages of 4 photos each in a 2x2 grid for all photos in current folder where the collage is 100x150mm in size with 300dpi saved as jpg
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import os | |
import glob | |
import subprocess | |
# this script needs imagemagick and can be installed with the following command on MacOS: | |
# brew install imagemagick | |
# is_landscape checks whetherimage file is landscape oriented. Returns true or false | |
def is_landscape(filename): | |
command = ['identify', '-format', '%[orientation] %[w] %[h]', filename] | |
output = subprocess.check_output(command) | |
orientation, width, height = output.decode().split() | |
return (orientation == 'TopLeft' and int(width) > int(height)) | |
# Creates a 100x150 mm collage photo at 300 dpi and saves it as a jpeg. As parameters, | |
# 1) 4 photo files in a list and 2) an index of the first photo file must be specified. | |
# The index is used for the name of the collage file. | |
def create_collage(input_files, index=0): | |
# check if all photos are in landscape orientation, if so, create landscape collage | |
# if not create portrait collage | |
landscape = all(is_landscape(filename) for filename in input_files) | |
edge_a = 886 # 150 mm with 300 dpi is 1772 pixels. Divide by 2 to get cell edge length | |
edge_b = 590 # 100 mm with 300 dpi is 1181 pixels. Divide by 2 to get cell edge length | |
# Calculate the size of each cell in the collage | |
cell_width = edge_a if landscape else edge_b | |
cell_height = edge_b if landscape else edge_a | |
# Create the command to crop and resize each photo to fit a cell | |
command_template = "convert {input_file} -auto-orient -resize {width}x{height}^ -gravity center -extent {width}x{height} {output_file}" | |
# Create a list to store the output file names | |
output_files = [] | |
# Process each input photo | |
for i, input_file in enumerate(input_files): | |
# Create a unique output file name for this cell | |
output_file = f"collage/tmp/cell{i+1}.jpg" | |
# Execute the command to crop and resize the photo | |
command = command_template.format( | |
input_file=input_file, | |
width=cell_width, | |
height=cell_height, | |
output_file=output_file) | |
subprocess.run(command, shell=True, check=True) | |
# Add the output file name to the list | |
output_files.append(output_file) | |
# Create the command to assemble the cells into a 2x2 grid | |
output_filename = 'collage/collage-' + str(index) + '-' + str(index+4) + '.jpg' | |
command = "montage -tile 2x2 -geometry +0+0 {} {}".format(" ".join(output_files), output_filename) | |
# Execute the command to assemble the cells | |
subprocess.run(command, shell=True, check=True) | |
# Find all jpeg photos in current working directory. This function creates collages for each | |
# group of four photos. The collages are saved in a 'collage'-folder. | |
def create_collages(): | |
# Get all .jpeg or .jpg files in the current working directory | |
jpg_files = glob.glob("*.jpeg") + glob.glob("*.jpg") + glob.glob("*.JPG") + glob.glob("*.JPEG") | |
# Check if there are any jpeg files found, otherwise stop | |
if len(jpg_files) <= 0: | |
return | |
# Specify the directory and temporary path | |
directory_path = "./collage" | |
tmp_directory_path = "./collage/tmp" | |
# Create the directory if it doesn't already exist | |
if not os.path.exists(directory_path): | |
os.makedirs(directory_path) | |
if not os.path.exists(tmp_directory_path): | |
os.makedirs(tmp_directory_path) | |
# Sort the images alphabetically. This make sure that photos are | |
# grouped in a collage in sequential order | |
sorted_images = sorted(jpg_files) | |
# Create groups with 4 photos each. Please note that the current working directory | |
# must contain a multiple of 4 photos in order for each photo to end up in a collage | |
for i in range(0, len(sorted_images), 4): | |
group = sorted_images[i:i+4] | |
if(len(group) == 4): | |
print(group) | |
create_collage(group, i) | |
if __name__ == "__main__": | |
create_collages() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment