我想制作一个模板,用于在 DIN A4 纸上打印 9 张 63 x 88 毫米的卡片。
我想加载图像以便它们可以自行调整大小并且我可以直接打印它们。
我怎样才能做到这一点?
答案1
下面是一个从多个图像创建一个文件的脚本。该脚本使用imagemagick
。
关于 imagemagick
从man imagemagick
:
ImageMagick® 是一款用于创建、编辑和合成位图图像的软件套件。它可以读取、转换和写入各种格式(约 100 种)的图像,包括 GIF、JPEG、JPEG-2000、PNG、PDF、PhotoCD、TIFF 和 DPX。使用 ImageMagick 可以平移、翻转、镜像、旋转、缩放、剪切和变换图像,调整图像颜色,应用各种特殊效果,或绘制文本、线条、多边形、椭圆和贝塞尔曲线。
由于 Imagemagick 是一个命令行工具,它特别适合在脚本中使用;例如自动执行您在问题中提到的工作。
安装 Imagemagick
您可能必须先安装 imagemagick:
sudo apt-get install imagemagick
剧本
该脚本将多个图像组合并排列成一个文件。这样做会占用px
您定义的最大空间(单位为 ),但不改变图像比例。一旦作业完成,输出将自动在中打开Gimp
(因此Gimp
应该安装)。如果出于某种原因文件未显示在中Gimp
,则它位于图像文件夹中,名为:out_file.jpg
。
一个例子
在下面的示例中,您想要的输出是一张包含三幅图像(列)x 三幅图像(行)的表格,而图像需要为 1500px(水平)。您需要一个 4500px(宽度)的区域,同时确保三行适合该区域。在脚本的头部部分,您设置:
colrows = [3, 3] # set the number of colums/rows
max_area = [4500, 6500] # set the area (hxv in px) the script can use
由于我们的图片的高度“过大”,脚本将填满最大宽度(每张图片 4500/3 = 1500px)
输出:
该脚本假设:
- 所有图片的比例和方向都相同(但尺寸可能不同)
- 文件夹内的图片数量(见上文)等于(或至少)行 x 列(示例中为 9)。如果文件夹内有更多图片,则仅使用所需数量。
选项/设置
该脚本有许多选项。在脚本的头部,您需要定义:
img_dir = "/path/to/files" # path to the images
output_extension = ".jpg" # desired output
colrows = [3, 3] # columns / rows of pictures
max_area = [4500, 6500] # the (max) size of your sheet
border = 10 # whitespace around the images
剧本
#!/usr/bin/env python3
import os
import subprocess
import shutil
# set the input below
###############################################################################
img_dir = "/path/to/files" # path to the images
output_extension = ".jpg" # desired output
colrows = [3, 3] # columns / rows of pictures
max_area = [4500, 6500] # the (max) size of your sheet
border = 10 # whitespace around the images
###############################################################################
cd_topics = "cd "+"'"+img_dir+"'; "
# current picture size
images = sorted([item for item in os.listdir(img_dir)])[:colrows[0]*colrows[1]]
for image in images:
shutil.copyfile(img_dir+"/"+image, img_dir+"/fixed_"+image.replace(" ", "_"))
images = sorted([item for item in os.listdir(img_dir) if item.startswith("fixed_")]) ##
# a few functions
def get_picsize(image):
command = cd_topics+'identify -format "%wx%h" '+image
return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8").strip().split("x")
def resize(img_in, img_out, size, modus=None):
modus = "^ " if modus == "outsize" else " "
newsize = str(size)+"x"+str(size)
resize_command = cd_topics+"convert "+img_in+" -resize "+newsize+modus+img_out
subprocess.call(["/bin/bash", "-c", resize_command])
def add_border(img_in, img_out, bd):
if bd != None and str(bd) != "0":
addborder_command = cd_topics+"convert "+img_in+" -bordercolor white -border "+bd+"x"+bd+" "+img_out
subprocess.call(["/bin/bash", "-c", addborder_command])
# make all pictures of equal size
standard_size = get_picsize(images[0])
for pic in images:
if not get_picsize(pic) == standard_size:
resize(pic, pic, max(standard_size))
# calculate resize
picture_orientation = int(standard_size[0])/int(standard_size[1])
area_ratio = float(max_area[0]/max_area[1])
combi_ratio = (colrows[0]*int(standard_size[0]))/(colrows[1]*int(standard_size[1]))
fit_in = area_ratio/combi_ratio
if fit_in > 1:
newsize = int(max_area[1]/colrows[1])-2*border
modus = "outsize" if picture_orientation > 1 else None
else:
newsize = int(max_area[0]/colrows[0])-2*border
modus = "outsize" if picture_orientation < 1 else None
# resize images
for image in images:
resize(image, "rs_"+image, newsize, modus)
add_border("rs_"+image, "rs_"+image, bd=str(border))
# combining into rows
images = sorted([pic for pic in os.listdir(img_dir) if pic.startswith("rs_")])
rows = [images[i:i+colrows[0]] for i in range(len(images)-colrows[0]+1) if i % colrows[0]== 0]
i = 0
while i in range(len(rows)):
row = rows[i]; images = [im for im in row]
command = cd_topics+"convert "+" ".join(images)+" +append "+"row_"+str(i+1)+output_extension
subprocess.call(["/bin/bash", "-c", command])
i = i+1
# combining rows
images = sorted([pic for pic in os.listdir(img_dir) if pic.startswith("row")])
output_file = "out_file"+output_extension
command = cd_topics+"convert "+(" ").join(images)+" -append "+output_file
subprocess.call(["/bin/bash", "-c", command])
# opening image with Gimp, cleaning up
for image in sum([[img for img in os.listdir(img_dir) if img.startswith(string)] \
for string in ["fixed_", "row_", "rs_"]], []):
os.remove(img_dir+"/"+image)
command = cd_topics+"gimp "+output_file
subprocess.Popen(["/bin/bash", "-c", command])
如何使用
- 将脚本复制到一个空文件中,将其另存为
combine.py
。在脚本的头部部分设置所需的信息(参见Options / settings
上文)。 - 将适当数量的图片复制到文件夹中
通过以下命令运行脚本:
python3 /path/to/combine.py
几点说明
- 脚本会创建一个新图像 (
outfile
)。如果您对相同的图片 (-directory) 进行另一种组合,请先将其删除,否则它可能会出现在输出文件中。 - 脚本按名称对图像进行排序,因此如果您需要特定顺序,只需将它们命名为 a.jpg、b.jpg 等等。