libvips будет читать только ту часть, которая вам нужна, когда это возможно. Например, если вы обрежете 100 x 100 пикселей из верхнего левого угла большого PNG-файла, это будет быстро:
$ 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
Вот обрезка и сохранение в Python с использованием pyvips:
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
— необязательный аргумент для установки Q-фактора JPG. Вы можете установить любой из параметров сохранения файла.
person
jcupitt
schedule
22.01.2018
ssh
войти на сервер NFS и использоватьvips
для извлечения оттуда? - person Mark Setchell   schedule 16.01.2018