在python中创建图片的蒙太奇

use*_*679 5 python image

我没有使用python的经验,但是此脚本的所有者没有响应。

当我将照片拖到该脚本上以创建蒙太奇时,它最终会切掉右侧边缘上最后一张照片的一半。

宽4张

1   2   3   4

5   6   7   8
Run Code Online (Sandbox Code Playgroud)

图片4和8通常会减半。那里有图片的空间(虽然空白)

我想知道是什么原因造成的。

我以为有可能被裁剪了,但是几乎就像一半的图片没有被导入或检测到一样。

好吧,将选定的照片拖到脚本上,它会输出类似这样的内容 http://i.imgur.com/PzNylbV.png

因此,您可以拍摄一堆照片或屏幕截图,并将它们组合到一个文件中,而无需单独添加每张照片。

每张照片的大小最大约为500x250。

在此处输入图片说明

编辑:这是预览的上载,因为您可以看到图像具有插槽,但是如果有意义的话,它们将“消失”。

EDIT2:该脚本一次起作用了,我没有对其进行任何编辑。它已经完成了约70个屏幕快照蒙太奇。没有错误或任何东西。我的计算机可能会做些事情来干扰图像的导入吗?

#!/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)
Run Code Online (Sandbox Code Playgroud)

phi*_*hag 6

在尺寸计算中,您使用image.size[1]宽度,但这就是高度!使用image.size[0]的宽度和image.size[1]对高度来代替。

另外,还有一些次要的风格注释:

  • 您是否真的需要脚本始终从程序目录运行?在任何情况下,都os.chdir(os.path.dirname(sys.argv[0]))禁止以方式执行程序./montage.py,因此您可能需要使用a abspath来允许从当前目录进行调用。
  • 无需更新计数器i,您可以将for循环更改为

    for i,image in enumerate(images):
    
    Run Code Online (Sandbox Code Playgroud)
  • 由于变量已被覆盖/从未使用过,因此以下几行无效:

    width = 0
    height = 0
    i = 0
    sum_x = max_y = 0 
    
    Run Code Online (Sandbox Code Playgroud)

总而言之,代码可能如下所示:

#!/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)
Run Code Online (Sandbox Code Playgroud)