libvips 将在可能的情况下仅读取您需要的部分。例如,如果您从大 PNG 的左上角裁剪 100x100 像素,则速度很快:
$ time vips crop wtc.png x.jpg 0 0 100 100
real 0m0.063s
user 0m0.041s
sys 0m0.023s
(四个数字分别是要从wtc.png裁剪并写入x.jpg的区域的左、上、宽、高)
但是从底部附近开始的 100x100 像素区域相当慢,因为它必须在您想要到达文件中正确点的像素之前读取和解压缩像素:
$ time vips crop wtc.png x.jpg 0 9000 100 100
real 0m3.063s
user 0m2.884s
sys 0m0.181s
JPG 和剥离 TIFF 的工作方式相同,但不太明显,因为它们是更快的格式。
某些格式支持真正的随机访问读取。例如,平铺 TIFF 在任何地方都很快,因为 libvips 可以使用 libtiff 来仅读取它需要的切片:
$ vips copy wtc.png wtc.tif[tile]
$ time vips crop wtc.tif x.jpg 0 0 100 100
real 0m0.033s
user 0m0.013s
sys 0m0.021s
$ time vips crop wtc.tif x.jpg 0 9000 100 100
real 0m0.037s
user 0m0.021s
sys 0m0.017s
OpenSlide、vips、平铺 OpenEXR、FITS、二进制 PPM/PGM/PBM、HDR、RAW、Analyze、Matlab 以及可能其他一些都支持像这样的真正随机访问。
如果您对更多细节感兴趣,API 文档中有一个章节描述了 libvips 如何打开文件:
http://libvips.github.io/libvips/API/current/How-it-opens-files.md.html
这是使用 pyvips 在 Python 中进行的裁剪和保存:
import pyvips
image = pyvips.Image.new_from_file(input_filename, access='sequential')
tile = image.crop(left, top, width, height)
tile.write_to_file(output_filename)
access= 是一个标志,它向 libvips 提示可以流式传输此图像,以防底层文件格式不支持随机访问。对于支持随机访问的格式,例如平铺的 TIFF,您不需要它。
您不需要写入文件。例如,这将创建一个缓冲区对象,其中包含编码为 JPG 的文件:
buffer = tile.write_to_buffer('.jpg', Q=85)
或者这会直接写到stdout:
target = pyvips.Target.new_from_descriptor(0)
tile.write_to_target('.jpg', Q=85)
Q=85 是设置 JPG Q 因子的可选参数。可以设置any of the file save options。