简体   繁体   English

Python PIL-在数组中连接图像

[英]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 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. 我有这个脚本,应该将一堆图像放在一个文件夹中(分别命名为Image 001,Image 002,Image 003等),然后将它们拼接成更少的图像。 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): 这是一个10 x 10输出图像的示例(来自Biggie Smalls音乐视频“ Juicy”的前100帧@ 10FPS):

在此处输入图片说明

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. 答案很简单:您无法将1024除以10,剩下的还有4个像素。

In Python 2, division is truncating if operands are integer: 在Python 2中,如果操作数是整数,则除法会被截断:

>>> 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. 例如,将10列的宽度从1024减小到1020。

  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. 好的,由于亚历山大(Alexanderlukanin)13识别了问题,因此我已解决了问题。 I basically changed 1024/10 into 1024/10 + 1024%10 so to add in the remainder. 我基本上将1024/10更改为1024/10 + 1024%10以便添加其余部分。 This even works for odd numbered resolutions (like 3x3 or 7x7, etc). 这甚至适用于奇数分辨率(例如3x3或7x7等)。

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. 它最初设置为1024x1024,因为一个名为Roblox的网站会在上传图片时自动将图片限制为该图片。

Lastly, I removed the sys way of printing percentage complete because I didn't need it with print available. 最后,我删除了完成打印百分比的sys方法,因为不需要可用的print The only reason I tried using sys was to automatically update a line with the percentage rather than print a new line. 我尝试使用sys的唯一原因是使用百分比自动更新一行,而不是打印新行。 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))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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