多页文档(PDF 与 TIFF)、分块(Tile)与金字塔(Pyramid)导出
除 GIF/WebP 动图外,libvips 的多页模型(page 与 n)还支撑着两类核心企业级工作流:
- 多页文档按页光栅化(PDF / 多页扫描 TIFF):从数百页的 PDF 或传真/医疗扫描 TIFF 中仅提取指定页码,并控制渲染 DPI(
Density); - 超大图像分块金字塔导出(Tiled Pyramidal TIFF / DeepZoom):将高分辨率航拍图、病理切片或古籍扫描导出为带多级分辨率子目录(Sub-IFD)的分块 TIFF,供查看器按块随机读取。
1. 按页加载 PDF 并控制光栅化 DPI
Section titled “1. 按页加载 PDF 并控制光栅化 DPI”对于数百页的 PDF,切勿使用 n=-1 一次性加载全部页面。应当先通过头部探测读取总页数(Pages() / metadata.pages),再通过 Page(0-indexed 起始页码)和 NumPages: 1 仅渲染目标页:
package main
import ( "fmt" "os"
"github.com/davidbyttow/govips/v2/vips")
func main() { if err := vips.Startup(nil); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } defer vips.Shutdown()
// 仅光栅化第 3 页(0-indexed 为 page=2),并将渲染分辨率设为 150 DPI(默认 72 DPI) params := vips.NewImportParams() params.Page.Set(2) params.NumPages.Set(1) params.Density.Set(150)
pageImg, err := vips.LoadImageFromFile("document.pdf", params) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } defer pageImg.Close()
// PDF 页面可能带透明背景:若需导出为白底图像,先执行 Flatten if pageImg.HasAlpha() { if err := pageImg.Flatten(&vips.Color{R: 255, G: 255, B: 255}); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } }
webpData, _, err := pageImg.ExportWebp(vips.NewWebpExportParams()) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } if err := os.WriteFile("page-3.webp", webpData, 0o644); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) }}import sharp from 'sharp';
// page: 2(第 3 页,从 0 开始计数),pages: 1,density: 150 DPIawait sharp('document.pdf', { page: 2, pages: 1, density: 150,}) .flatten({ background: '#ffffff' }) .webp({ quality: 82 }) .toFile('page-3.webp');import pyvips
# 先读取第 0 页获取总页数 ("n-pages")first = pyvips.Image.new_from_file("document.pdf", page=0, n=1)total_pages = first.get("n-pages")
# 按需渲染第 3 页(page=2),DPI 设为 150page_img = pyvips.Image.new_from_file("document.pdf", page=2, n=1, dpi=150)if page_img.hasalpha(): page_img = page_img.flatten(background=[255, 255, 255])
page_img.write_to_file("page-3.webp", Q=82)#!/usr/bin/env bashset -euo pipefail
# 查看总页数vipsheader -f n-pages document.pdf
# 仅以 150 DPI 渲染第 3 页 (page=2, n=1) 并导出为 WebPvips pdfload document.pdf 'page-3.webp[Q=82]' --page 2 --n 1 --dpi 1502. 导出分块金字塔 TIFF(Tiled Pyramidal TIFF)
Section titled “2. 导出分块金字塔 TIFF(Tiled Pyramidal TIFF)”在医疗数字病理(WSI)、地理信息系统(GIS)和博物馆高精馆藏中,金字塔 TIFF(Pyramidal TIFF)是标准交换格式:文件内部不仅按 256 × 256 瓦片(Tile)分块存储以支持任意视口随机读取,还内置了逐级减半的下采样金字塔层。
| TIFF 导出参数 | govips TiffExportParams |
sharp .tiff(options) |
pyvips / vips CLI tiffsave |
说明 |
|---|---|---|---|---|
| 压缩算法 | Compression(TiffCompressionDeflate / Lzw / Jpeg / Zstd / Webp) |
compression('deflate' / 'lzw' / 'jpeg' / 'zstd' / 'webp') |
compression="deflate" |
无损归档推荐 deflate 或 zstd;切片预览可用 jpeg / webp |
| 差分预测器 | Predictor(TiffPredictorHorizontal) |
predictor('horizontal') |
predictor="horizontal" |
配合 lzw 或 deflate 可显著提高连续色调图像的无损压缩率 |
| 瓦片分块模式 | Tile: true、TileWidth: 256、TileHeight: 256 |
tile: true、tileWidth: 256、tileHeight: 256 |
tile=True, tile_width=256, tile_height=256 |
将默认的条带(Strip)存储改为二维网格瓦片 |
| 多分辨率金字塔 | Pyramid: true |
pyramid: true |
pyramid=True / --pyramid |
自动生成逐级 1/2 缩小的金字塔层(通常配合 subifd=True) |
| 64 位偏移量 | BigTiff: true |
bigtiff: true |
bigtiff=True / --bigtiff |
当输出 TIFF 可能超过 4 GB 时必须开启 |
tiffParams := vips.NewTiffExportParams()tiffParams.Compression = vips.TiffCompressionDeflatetiffParams.Predictor = vips.TiffPredictorHorizontaltiffParams.Tile = truetiffParams.TileWidth = 256tiffParams.TileHeight = 256tiffParams.Pyramid = truetiffParams.BigTiff = true
data, _, err := image.ExportTiff(tiffParams)if err != nil { return err}return os.WriteFile("pyramid.tif", data, 0o644)import sharp from 'sharp';
await sharp('input.jpg') .tiff({ compression: 'deflate', predictor: 'horizontal', tile: true, tileWidth: 256, tileHeight: 256, pyramid: true, bigtiff: true, }) .toFile('pyramid.tif');import pyvips
image = pyvips.Image.new_from_file("input.jpg")image.write_to_file( "pyramid.tif", compression="deflate", predictor="horizontal", tile=True, tile_width=256, tile_height=256, pyramid=True, subifd=True, bigtiff=True,)vips tiffsave input.jpg pyramid.tif \ --compression deflate \ --predictor horizontal \ --tile \ --tile-width 256 \ --tile-height 256 \ --pyramid \ --subifd \ --bigtiffgovips v2.20.0 会在 Rotate、Flip、Zoom 与 Resize 时保持已加载多页长卷的页序和 page-height;这项保证不包括 Similarity、SmartCrop 与 Gravity。动图场景的完整边界见动画与多页图像。