Skip to content
所有文章 ‹ Part 06 of 07 · 裁切、縮放、填滿:圖片處理
工程 · 1 min read

一條載入路徑,同時吃靜圖與動圖

給 libvips loader 一個 n=-1,一條無條件路徑就能同時吃靜圖與動圖——因為預設的 n=1 只會默默解出第一格,把動畫悄悄丟掉。

載入時給 libvips 的 loader 一個 n=-1。一條無條件的路徑就能吃下所有輸入。不用嗅格式,也不用分幾頁的分支。

importParams := vips.NewImportParams()
importParams.NumPages.Set(-1) // -1 = load ALL pages/frames
image, err := vips.LoadImageFromBuffer(imageBytes, importParams)

NumPages 對到 loader 的 n。-1 的意思是「有幾頁就讀幾頁」:

  • 動圖 GIF(5 格) → 疊成 5 頁 → Pages() == 5。
  • 單張圖(JPEG/PNG/靜態 GIF) → 剛好 1 頁 → Pages() == 1、PageHeight() == Height()。這裡的 -1 是不折不扣的 no-op。不會回「0 格」,也不會出錯。

所以「單張還是多張」是載入之後用 Pages()、PageHeight() 判斷的。不在載入那一行決定。-1 也跟格式無關,animated WebP/AVIF、multi-page TIFF/PDF 全走同一條路。就算註解寫「for GIFs」也一樣。

那個坑:預設 n=1 會默默丟掉動畫

loader 的 n 預設是 1。所以一張 GIF 只會載第 0 頁。其餘影格連解碼都沒有,loader 安靜地丟掉動畫,你拿到的是第一格的靜圖:

5 格的 GIF 5 格疊起來 載入 n = 1 frame 0 — 保留 frame 1–4 被丟掉 沒有例外 · 沒有警告 Pages() = 1 → 被當成一張靜圖 · 動畫掉了
預設 n = 1 只解第 0 頁。解法是用 n = -1 載入。

沒有例外、沒有警告。失敗方式就是「動畫悄悄不見」,這正是為什麼那個 -1 要緊。

預設值不是中性的。沒讀到的影格,它不會吭一聲就丟掉。


參考來源:

延伸閱讀:

↑↓ 移動 ↵ 開啟 esc 關閉