使用 libvips 重新缩放图像

Rescaling an image with libvips

我有一张 6130x5548 pixels 的图像,我想重新缩放它,使最长的边为 32768 pixels(然后制作一个具有 7 个缩放级别的金字塔)。我不明白 vips resize 是类似的明显方式,因此我尝试了下面的行

vips resize image_in.tif img_rescaled.tif 5.345513866231648

数字5.34551只是比例32768/6130,我x axis的比例因子。如果我想指定返回图像的精确尺寸(以像素为单位),我该怎么做?

我尝试使用 vips thumbnail 来达到这个目的,我不知道是否推荐这样做,但它确实有效。

vips thumbnail image_in.tif img_rescaled.tif 32768

这样可以吗?

此外,这两种方法在 MB 大小方面给出了完全不同的输出。虽然 vips thumbnail 生成大小为 2.8Gbtif,但 vips resize 调用 returns 大小为 1.8Gbtif

两个图像(显然)具有相同的尺寸 32768x29657 pixels、相同的分辨率 72dpi 但不同 bit depth 来自 vips thumbnailtif 24 bit depth 而来自 vips resize 16 bit depth 的那个。原图有bit depth=16.

此外,据我所知,vips translate 使用的算法对生成的文件大小起着重要作用。 vips thumbnail and/or 和 bit depth 可以设置算法吗?

resize只取一个比例因子,所以需要自己计算。您可以使用类似的东西:

width=$(vipsheader -f width somefile.tif)
height=$(vipsheader -f height somefile.tif)
size=$((width > height ? width : height))
factor=$(bc <<< "scale=10; 32768 / $size")
vips resize somefile.tif huge.tif $factor

我会在升级前使用 8 位,因为显示只需要 8 位。您可以使用:

vips colourspace thing.tif other.tif srgb

制作 8 位 srgb 版本。

当你开始做这样的事情时,

bash 变得如此丑陋,以至于我很想切换到 pyvips

import pyvips

image = pyvips.Image.new_from_file('somefile.tif', access='sequential')
image = image.colourspace('srgb')
image = image.resize(32768 / max(image.width, image.height))
image.dzsave('mypyramid')

它有一个额外的优势,那就是它不会使用任何临时文件。 pyvips 构建图像处理操作的管道,因此该程序将从您的输入中流式传输像素,放大它们,并同时并行地写入金字塔。它不会占用太多内存,而且速度很快。