用pyvips加入多个巨大的图像

时间:2018-03-24 04:53:24

标签: python image image-processing vips

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

如果我尝试将它们与MemmoryError水平连接在一起,那么python中的PIL会立即死掉。所以我谷歌周围找到VIPS,可以做我需要的两件事加入图像,并从结果制作深度缩放图像。

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

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

3 个答案:

答案 0 :(得分:2)

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

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

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

http://jcupitt.github.io/libvips/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上,由于Windows讨厌创建文件并且讨厌巨大的目录,因此深度展示金字塔的编写速度非常慢。如果您使用container=zip编写,则vips将直接创建包含金字塔的.zip文件。这使金字塔的创建速度提高了约4倍。

答案 1 :(得分:0)

我还想出了一些问题:

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!什么给出了,为什么会出现这么大的差异?

答案 2 :(得分:0)

这似乎也适用于打开大量图像并对它们进行连接阵列,因此它们彼此相邻。谢谢@ 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)