Creating a montage of pictures in python

2024/11/15 16:18:45

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   45   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 http://i.imgur.com/PzNylbV.png

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.

enter image description here

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 = 3def generate_montage(filenames):images = [Image.open(filename) for filename in filenames]width = 0height = 0i = 0sum_x = max_y = 0 width = max(image.size[1]+margin for image in images)*row_sizeheight = 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 = 0i = 0max_y = 0max_x = 0offset_x = 0for image in images:montage.paste(image, (offset_x, offset_y))text_coords = offset_x + image.size[0] - 45, offset_y + 120draw.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+marginmax_y = 0offset_x = 0else:offset_x += image.size[0]+marginmax_y = max(max_y, image.size[1])i += 1if i % row_size:offset_y += max_yfilename = 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)
Answer

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:

  • Do you really need the script to always run from the program's directory? In any case, 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 Imagerow_size = 4
margin = 3def generate_montage(filenames, output_fn):images = [Image.open(filename) for filename in filenames]width = max(image.size[0] + margin for image in images)*row_sizeheight = sum(image.size[1] + margin for image in images)montage = Image.new(mode='RGBA', size=(width, height), color=(0,0,0,0))max_x = 0max_y = 0offset_x = 0offset_y = 0for 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 + marginoffset_x = 0else: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)
https://en.xdnf.cn/q/71864.html

Related Q&A

stop python program when ssh pipe is broken

Im writing a python script with an infinite while loop that I am running over ssh. I would like the script to terminate when someone kills ssh. For example:The script (script.py):while True:# do someth…

How do I export a TensorFlow model as a .tflite file?

Background information:I have written a TensorFlow model very similar to the premade iris classification model provided by TensorFlow. The differences are relatively minor: I am classifying football ex…

Using plotly in Jupyter to create animated chart in off-line mode

Ive been trying to get the "Filled-Area Animation in Python" example to work using plotly in offline mode in a Jupyter notebook. The example can be found here: https://plot.ly/python/filled-a…

Django: How to unit test Update Views/Forms

Im trying to unit test my update forms and views. Im using Django Crispy Forms for both my Create and Update Forms. UpdateForm inherits CreateForm and makes a small change to the submit button text. Th…

Why is Python faster than C++ in this case?

A program in both Python and C++ is given below, which performs the following task: read white-space delimited words from stdin, print the unique words sorted by string length along with a count of eac…

Python - write headers to csv

Currently i am writing query in python which export data from oracle dbo to .csv file. I am not sure how to write headers within file. try:connection = cx_Oracle.connect(user,pass,tns_name)cursor = con…

Opening/Attempting to Read a file [duplicate]

This question already has answers here:PyCharm shows unresolved references error for valid code(31 answers)Closed 5 years ago.I tried to simply read and store the contents of a text file into an array,…

How to pass custom settings through CrawlerProcess in scrapy?

I have two CrawlerProcesses, each is calling different spider. I want to pass custom settings to one of these processes to save the output of the spider to csv, I thought I could do this:storage_setti…

numpy how to slice index an array using arrays?

Perhaps this has been raised and addressed somewhere else but I havent found it. Suppose we have a numpy array: a = np.arange(100).reshape(10,10) b = np.zeros(a.shape) start = np.array([1,4,7]) # ca…

How to import _ssl in python 2.7.6?

My http server is based on BaseHTTPServer with Python 2.7.6. Now I want it to support ssl transportation, so called https.I have installed pyOpenSSL and recompiled python source code with ssl support. …