Reputation: 4233
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.
Upvotes: 0
Views: 424
Reputation: 4233
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))
Upvotes: 0
Reputation: 4715
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:
Adjust size dynamically according to rows and columns count. For example, reduce width from 1024 to 1020 for 10 columns.
If you are generally okay with black padding, just make them equal at left-right and top-bottom edges.
Upvotes: 2