在python中创建蒙太奇的图片 [英] Creating a montage of pictures in python

查看:183
本文介绍了在python中创建蒙太奇的图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

宽4张图片,

1   2   3   4

5   6   7   8

图片4和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

因此,您可以拍摄大量照片或屏幕截图,并将它们合并为一个文件,而不是单独添加每张照片。

So you can take a bunch of photos or screenshots, and combine them into one single file, easily instead of adding each photo individually.

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

Size of each photo is roughly 500x250 at max.

编辑:
这是预览的上传,因为你可以看到图像有插槽,但如果有意义,它们就会消失。

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:
这个脚本一次有效,我有没有编辑它或任何东西。它已经制作了约70个截图蒙太奇。没有错误或任何事情。我的计算机可以做些什么来破坏图像的导入吗?

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 = 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)


推荐答案

在尺寸计算中,您使用 image.size [1] 作为宽度,但这就是高度!对于宽度使用 image.size [0] ,而使用 image.size [1] 作为高度。

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:


  • 你真的需要这个剧本吗?总是从程序的目录运行?在任何情况下, os.chdir(os.path.dirname(sys.argv [0]))都会阻止程序以 ./执行。 montage.py ,所以你可能想要使用 abspath 允许从当前目录调用。

  • 而不是必须更新计数器 i ,您可以将for循环更改为

  • 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 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)
    

    这篇关于在python中创建蒙太奇的图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆