Engineering · 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 頁。其餘影格連解碼都沒有,動畫被安靜地丟掉,你拿到的是第一格的靜圖:
n = 1 只解第 0 頁——解法是用 n = -1 載入。沒有例外、沒有警告,失敗方式就是「動畫悄悄不見」,這正是為什麼那個 -1 要緊。
預設值不是中性的:沒讀到的影格,它不會吭一聲就丟掉。
參考來源:
Related: 這一步接續libvips 把動圖存成一條上下疊起來的長條,也接到均勻變換 vs 定位變換:在拼接長條上的差別,或回到裁切、縮放、填滿的四堂課總覽。