I have no experience with python, but the owner of this script is not responding.
When I drag my photos over this script, to create a montage, it ends up cutting off half of the last photo on the right side edge.
Being 4 pictures wide,
1 2 3 4
5 6 7 8
Pictures 4 and 8 usually get halved. The space is there for the pictures (its blank though)
I was wondering what would be causing this.
I have thought it is possible that it was cropping, but its almost like the half of the picture isn't imported or detected.
Well, you drag selected photos over the script , it outputs something like this
So you can take a bunch of photos or screenshots, and combine them into one single file, easily instead of adding each photo individually.
Size of each photo is roughly 500x250 at max.
EDIT: Here is the upload of the preview, as you can see the images have the slots, but they are "disappearing" if that makes sense.
EDIT2: This script has worked at one time, I haven't edited it or anything. It had worked on a ~70 screenshot montage. No errors or anything. Is there something that my computer could be doing to disrupt the importing of the images?
#!/usr/bin/env python
import os
import sys
from time import strftime
import Image
import ImageDraw
import ImageFont
# parameters
row_size = 4
margin = 3
def generate_montage(filenames):
images = [Image.open(filename) for filename in filenames]
width = 0
height = 0
i = 0
sum_x = max_y = 0
width = max(image.size[1]+margin for image in images)*row_size
height = sum(image.size[0]+margin for image in images)
montage = Image.new(mode='RGBA', size=(width, height), color=(0,0,0,0))
try:
image_font = ImageFont.truetype('font/Helvetica.ttf', 18)
except:
try:
image_font = ImageFont.load('font/Helvetica-18.pil')
except:
image_font = ImageFont.load_default()
draw = ImageDraw.Draw(montage)
offset_x = offset_y = 0
i = 0
max_y = 0
max_x = 0
offset_x = 0
for image in images:
montage.paste(image, (offset_x, offset_y))
text_coords = offset_x + image.size[0] - 45, offset_y + 120
draw.text(text_coords, '#{0}'.format(i+1), font=image_font)
max_x = max(max_x, offset_x+image.size[0])
if i % row_size == row_size-1:
offset_y += max_y+margin
max_y = 0
offset_x = 0
else:
offset_x += image.size[0]+margin
max_y = max(max_y, image.size[1])
i += 1
if i % row_size:
offset_y += max_y
filename = strftime("Montage %Y-%m-%d at %H.%M.%S.png")
montage = montage.crop((0, 0, max_x, offset_y))
montage.save(filename)
if __name__ == '__main__':
old_cwd = os.getcwd()
os.chdir(os.path.dirname(sys.argv[0]))
try:
if len(sys.argv) > 1:
generate_montage(sys.argv[1:])
finally:
os.chdir(old_cwd)
In the size calculation, you use image.size[1]
for the width, but that's the height! Use image.size[0]
for the width and image.size[1]
for the height instead.
Also, a couple of minor stylistic notes:
os.chdir(os.path.dirname(sys.argv[0]))
prevents the program from being executed as ./montage.py
, so you may want to use a abspath
to allow the invocation from the current directory.Instead of having to update the counter i
, you can change the for loop to
for i,image in enumerate(images):
The following lines have no effect, since the variables are overwritten / never used:
width = 0
height = 0
i = 0
sum_x = max_y = 0
All in all, the code could look like this:
#!/usr/bin/env python
import os.path
import sys
from time import strftime
import Image
row_size = 4
margin = 3
def generate_montage(filenames, output_fn):
images = [Image.open(filename) for filename in filenames]
width = max(image.size[0] + margin for image in images)*row_size
height = sum(image.size[1] + margin for image in images)
montage = Image.new(mode='RGBA', size=(width, height), color=(0,0,0,0))
max_x = 0
max_y = 0
offset_x = 0
offset_y = 0
for i,image in enumerate(images):
montage.paste(image, (offset_x, offset_y))
max_x = max(max_x, offset_x + image.size[0])
max_y = max(max_y, offset_y + image.size[1])
if i % row_size == row_size-1:
offset_y = max_y + margin
offset_x = 0
else:
offset_x += margin + image.size[0]
montage = montage.crop((0, 0, max_x, max_y))
montage.save(output_fn)
if __name__ == '__main__':
basename = strftime("Montage %Y-%m-%d at %H.%M.%S.png")
exedir = os.path.dirname(os.path.abspath(sys.argv[0]))
filename = os.path.join(exedir, basename)
generate_montage(sys.argv[1:], filename)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With