繁体   English   中英

用pyvips连接多个巨大的图像

[英]Joining multiple huge images with pyvips

我想弄清楚如何通过 python 将多个图像与 vips 连接起来。 我在一个文件夹中有 30 个(但可以超过 600 个)条纹 png 文件,它们的分辨率为 854x289920(所有相同的分辨率)...

如果我尝试将它们与 MemmoryError 水平连接在一起,python 中的 PIL 将立即死亡。 所以我谷歌搜索并发现VIPS可以做我需要加入图像并从结果制作深度缩放图像的两件事。

不幸的是,我不确定如何在 python 中正确地水平连接它们。

我在数组中有一个来自文件夹的图像列表,但是我将如何遍历它们并依次将连接的图像写入磁盘?

仅供参考,您也可以在命令行执行此操作。 尝试:

vips arrayjoin "a.png b.png c.png" mypyr.dz --across 3

将水平连接三个 PNG 图像并将结果保存为名为mypyr的 deepzoom 金字塔。 arrayjoin 文档具有所有选项:

https://www.libvips.org/API/current/libvips-conversion.html#vips-arrayjoin

您可以通过将参数括在.dz之后的方括号中来提供金字塔构建器参数。

vips arrayjoin "a.png b.png c.png" mypyr.dz[overlap=0,container=zip] --across 3

在 Windows 上,deepzoom 金字塔的写入速度可能非常慢,因为 Windows 讨厌创建文件,并且讨厌巨大的目录。 如果使用container=zip编写,vips 将直接创建一个包含金字塔的 .zip 文件。 这使得金字塔创建速度提高了大约 4 倍。

我还是想出了一些问题:

import pyvips

list_of_pictures = []
for x in os.listdir(source):
    list_of_pictures.append(source + x)

image = None
for i in list_of_pictures:
    tile = pyvips.Image.new_from_file(i, access="sequential")
    image = tile if not image else image.join(tile, "horizontal")

image.write_to_file(save_to)

是的,生成带有连接图片的 tif ……但是冬青牛! 原始图片是 png (30x) 总共 4.5GB 结果 tiff 是 25GB! 什么给出了,为什么会有如此巨大的尺寸差异?

这似乎也适用于打开大量图像并对它们进行 joinarray 使它们彼此相邻。 谢谢@user894763

import os
import pyvips
# natsort helps with sorting the list logically
from natsort import natsorted

source = r"E:/pics/"
output = r"E:/out/"
save_to = output + 'final' + '.tif'

# define list of pictures we are going to get from folder
list_of_pictures = []
# get the 
for x in os.listdir(source):
    list_of_pictures.append(source + x)

# list_of_pictures now contains all the images from folder including full path
# since os.listdir will not guarantee proper order of files we use natsorted to do it
list_of_pictures = natsorted(list_of_pictures)

array_images = []
image = None
# lets create array of the images for joining, using sequential so it use less ram
for i in list_of_pictures:
    tile = pyvips.Image.new_from_file(i, access="sequential")
    array_images.append(tile)

# Join them, across is how many pictures there be next to each other, so i just counted all pictures in array with len 
out = pyvips.Image.arrayjoin(array_images, across=len(list_of_pictures))
# write it out to file....
out.write_to_file(save_to, Q=95, compression="lzw", bigtiff=True)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM