Last active
February 12, 2023 14:47
-
-
Save rueycheng/56389ff807a9732f9978e661ca3ff556 to your computer and use it in GitHub Desktop.
Fit multiple 35mm x 45mm passport photos into a 4x6-sized printable format
This file contains hidden or 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
import argparse | |
import math | |
from PIL import Image, ImageDraw | |
def main(): | |
parser = argparse.ArgumentParser() | |
parser.add_argument('-o', dest='output_file', required=True, help='output file') | |
parser.add_argument('input_files', metavar='FILE', nargs='+') | |
args = parser.parse_args() | |
def snap(x): | |
return int(math.ceil(x)) | |
# Load input files and resize all images | |
img = [Image.open(fname) for fname in args.input_files] | |
for i in range(1, len(img)): | |
img[i] = img[i].resize(img[0].size) | |
# Allocate slots | |
if len(img) in (1, 2, 4, 8): | |
rep = int(8 / len(img)) | |
slot = [] | |
for obj in img: | |
slot.extend([obj] * rep) | |
else: | |
print('Can only process 1, 2, or 4 input files') | |
return | |
# Assuming input is 35mm x 45mm, target (4x6) will be 101.6mm x 152.4mm in landscape | |
print('Image size:', img[0].size) | |
width, height = img[0].size | |
ppmm = width / 35 | |
new_width, new_height = snap(height / 45 * 152.4), snap(width / 35 * 101.6) | |
# New image in landscape | |
new_img = Image.new('RGB', (new_width, new_height), color='white') | |
print('Target size:', new_img.size) | |
offset = snap(ppmm) | |
margin_left = (new_width - 4 * (width + 2*offset)) / 2 | |
margin_top = (new_height - 2 * (height + 2*offset)) / 2 | |
new_draw = ImageDraw.Draw(new_img) | |
for i in range(4): | |
for j in range(2): | |
x = snap(margin_left + offset + i * (width + 2*offset)) | |
y = snap(margin_top + offset + j * (height + 2*offset)) | |
new_img.paste(slot[i+4*j], (x, y)) | |
new_draw.line((x-offset, y-offset, x+width+offset, y-offset), fill='#333333') | |
new_draw.line((x+width+offset, y-offset, x+width+offset, y+height+offset), fill='#333333') | |
new_draw.line((x-offset, y+height+offset, x+width+offset, y+height+offset), fill='#333333') | |
new_draw.line((x-offset, y-offset, x-offset, y+height+offset), fill='#333333') | |
new_img.save(args.output_file) | |
print(f'Output saved to {args.output_file}') | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment