我有一张图片列表,用来制作一个以某种模式命名的拼贴画。例如。
所有文件都在同一个目录中。目前,我只能发送一个命令来对文件夹中的所有图像进行拼贴,但我要做的是能够从shell命令中发送一个特定的关键字,并在文件夹中查找与关键字匹配的文件列表,然后进行拼贴。
例如。shell命令make_collage.py -o my_collage.png -w 540 -i 840新参数--> -a "_us“--运行该命令时,它将只使用包含关键字"_us”的文件进行拼贴。因此,输出将是一个只包含"_us“图像的拼贴图。
import argparse
import os
import random
from PIL import Image
def make_collage(images, filename, width, init_height):
"""
Make a collage image with a width equal to `width` from `images` and save to `filename`.
"""
if not images:
print('No images for collage found!')
return False
margin_size = 2
# run until a suitable arrangement of images is found
while True:
# copy images to images_list
images_list = images[:]
coefs_lines = []
images_line = []
x = 0
while images_list:
# get first image and resize to `init_height`
img_path = images_list.pop(0)
img = Image.open(img_path)
img.thumbnail((width, init_height))
# when `x` will go beyond the `width`, start the next line
if x > width:
coefs_lines.append((float(x) / width, images_line))
images_line = []
x = 0
x += img.size[0] + margin_size
images_line.append(img_path)
# finally add the last line with images
coefs_lines.append((float(x) / width, images_line))
# compact the lines, by reducing the `init_height`, if any with one or less images
if len(coefs_lines) <= 1:
break
if any(map(lambda c: len(c[1]) <= 1, coefs_lines)):
# reduce `init_height`
init_height -= 10
else:
break
# get output height
out_height = 0
for coef, imgs_line in coefs_lines:
if imgs_line:
out_height += int(init_height / coef) + margin_size
if not out_height:
print('Height of collage could not be 0!')
return False
collage_image = Image.new('RGB', (width, int(out_height)), (35, 35, 35))
# put images to the collage
y = 0
for coef, imgs_line in coefs_lines:
if imgs_line:
x = 0
for img_path in imgs_line:
img = Image.open(img_path)
# if need to enlarge an image - use `resize`, otherwise use `thumbnail`, it's faster
k = (init_height / coef) / img.size[1]
if k > 1:
img = img.resize((int(img.size[0] * k), int(img.size[1] * k)), Image.ANTIALIAS)
else:
img.thumbnail((int(width / coef), int(init_height / coef)), Image.ANTIALIAS)
if collage_image:
collage_image.paste(img, (int(x), int(y)))
x += img.size[0] + margin_size
y += int(init_height / coef) + margin_size
collage_image.save(filename)
return True
def main():
# prepare argument parser
parse = argparse.ArgumentParser(description='Photo collage maker')
parse.add_argument('-f', '--folder', dest='folder', help='folder with images (*.jpg, *.jpeg, *.png)', default='.')
parse.add_argument('-o', '--output', dest='output', help='output collage image filename', default='collage.png')
parse.add_argument('-w', '--width', dest='width', type=int, help='resulting collage image width')
parse.add_argument('-i', '--init_height', dest='init_height', type=int, help='initial height for resize the images')
parse.add_argument('-s', '--shuffle', action='store_true', dest='shuffle', help='enable images shuffle')
args = parse.parse_args()
if not args.width or not args.init_height:
parse.print_help()
exit(1)
# get images
files = [os.path.join(args.folder, fn) for fn in os.listdir(args.folder)]
images = [fn for fn in files if os.path.splitext(fn)[1].lower() in ('.jpg', '.jpeg', '.png')]
if not images:
print('No images for making collage! Please select other directory with images!')
exit(1)
# shuffle images if needed
if args.shuffle:
random.shuffle(images)
print('Making collage...')
res = make_collage(images, args.output, args.width, args.init_height)
if not res:
print('Failed to create collage!')
exit(1)
print('Collage is ready!')
if __name__ == '__main__':
main()发布于 2019-02-15 00:34:50
最简单的方法是使用glob.glob()和os.listdir(),尽管glob()使用bash语法,因此需要输入*_us*。
第一次进口:
from glob import glob然后添加一个“模式”可选位置arg:
parse.add_argument('-p', '--pattern', nargs="?", default=None, help="enter a grep-like expansion.")最后,将# get images下的行更改为如下所示:
if args.pattern:
files = [fn for fn in glob(os.path.join(args.folder, args.pattern))]
else:
files = [os.path.join(args.folder, fn) for fn in os.listdir(args.folder)]https://stackoverflow.com/questions/54700876
复制相似问题