在python中创建蒙太奇的图片(Creating a montage of pictures in python)

系统教程 行业动态 更新时间:2024-06-14 16:57:18
在python中创建蒙太奇的图片(Creating a montage of pictures in python)

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

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

4张照片,

1 2 3 4 5 6 7 8

图片4和8通常会减半。 照片的空间(尽管它是空白的)

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

我认为它可能是裁剪,但它几乎像图片的一半没有导入或检测到。

好吧,你将选定的照片拖到脚本上,输出这样的东西

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

每张照片的大小最大约为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)

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.

Being 4 pictures wide,

1 2 3 4 5 6 7 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.

Size of each photo is roughly 500x250 at max.

EDIT: 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: 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]作为高度。

还有一些小风格的笔记:

你真的需要脚本始终从程序的目录运行吗? 在任何情况下, os.chdir(os.path.dirname(sys.argv[0]))阻止程序以./montage.py形式执行,因此您可能希望使用abspath来允许从当前调用目录。

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

for i,image in enumerate(images):

以下行无效,因为变量被覆盖/从未使用过:

width = 0 height = 0 i = 0 sum_x = max_y = 0

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

#!/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)

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:

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)

更多推荐

本文发布于:2023-04-12 20:57:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/dzcp/cbe156e08cb6f5191a68eb2f9b0d4189.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:蒙太奇   图片   python   pictures   montage

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!