简体   繁体   中英

Python PIL - Joining images in an array

Edit: I've changed the title so its easier for people to find this useful code below in the answer. :)

Python 2.7.10

I have this script that is supposed to take a bunch of images in a folder (that are named Image 001, Image 002, Image 003, etc.) and stitch them together into fewer images. Here is an example of a 10 by 10 output image (from the first 100 frames @10FPS of the music video "Juicy" by Biggie Smalls):

在此处输入图片说明

import Image
import glob
import sys
name = raw_input('What is the file name (excluding the extension) of your video that was converted using FreeVideoToJPGConverter?\n')
rows = int(raw_input('How many rows do you want?\n'))
columns = int(raw_input('How many columns do you want?\n'))
images = glob.glob('../' + name + '*.jpg')
new_im = Image.new('RGB', (1024,1024))
x_cntr = 0 #X counter
y_cntr = 0 #Y counter
for x in xrange(0,len(images),1):
    if x%(rows*columns) == 0: #if the new image is filled, save it in output and create new one
        new_im.save('Output' + str(x) + '.jpg')
        new_im = Image.new('RGB', (1024,1024))
        y_cntr = 0
        x_cntr = 0
    elif x%rows == 0: #Else if a new row is completed, then go back to 0 on a new row
        x_cntr = 0
        y_cntr = y_cntr + 1024/columns
    elif x%1 == 0: #If no new row or image is complete, just add another image to the current row
        x_cntr = x_cntr + 1024/rows
    im = Image.open(images[x])
    im = im.resize((1024/rows, 1024/columns), Image.ANTIALIAS)
    new_im.paste(im, (x_cntr, y_cntr))
    sys.stdout.write("\r%d%%" % x/len(images))
    sys.stdout.flush()

Now, I don't know why there is a black line that is a few pixels wide that appears on the right and bottom of the image. Please let me know why this is and how I can fix this.

The answer is simple: you can't divide 1024 by 10, you'll get 4 pixels left.

In Python 2, division is truncating if operands are integer:

>>> 1024 / 10
102

To solve you problem, you have two options:

  1. Adjust size dynamically according to rows and columns count. For example, reduce width from 1024 to 1020 for 10 columns.

  2. If you are generally okay with black padding, just make them equal at left-right and top-bottom edges.

OK, so I've fixed my problem thanks to alexanderlukanin13 who identified the problem. I basically changed 1024/10 into 1024/10 + 1024%10 so to add in the remainder. This even works for odd numbered resolutions (like 3x3 or 7x7, etc).

I've also added an input for your resolution choice. It was originally set to 1024x1024 because a website called Roblox automatically limits images to that when they are uploaded.

Lastly, I removed the sys way of printing percentage complete because I didn't need it with print available. The only reason I tried using sys was to automatically update a line with the percentage rather than print a new line. I never figured out how to do it, but it doesn't really matter.

So here's the working code:

import Image
import glob
name = raw_input('What is the file name (excluding the extension) of your video that was converted using FreeVideoToJPGConverter?\n')
x_res = int(raw_input('What do you want the height of your image to be (in pixels)?\n'))
y_res = int(raw_input('What do you want the width of your image to be (in pixels)?\n'))
rows = int(raw_input('How many rows do you want?\n'))
columns = int(raw_input('How many columns do you want?\n'))
images = glob.glob('../' + name + '*.jpg')
new_im = Image.new('RGB', (x_res,y_res))
x_cntr = 0
y_cntr = 0
for x in xrange(0,len(images),1):
    if x%(rows*columns) == 0:
        new_im.save('Output' + str(x) + '.jpg')
        new_im = Image.new('RGB', (x_res,y_res))
        y_cntr = 0
        x_cntr = 0
        print str(round(100*(float(x)/len(images)), 1)) + "% Complete"
    elif x%rows == 0:
        x_cntr = 0
        y_cntr = y_cntr + y_res/columns
    elif x%1 == 0:
        x_cntr = x_cntr + x_res/rows
    im = Image.open(images[x])
    im = im.resize((x_res/rows + x_res%rows, y_res/columns + y_res%columns), Image.ANTIALIAS)
    new_im.paste(im, (x_cntr, y_cntr))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM