Skip to content
所有文章 ‹ Part 05 of 09 · 一次 Golang 版本升級的連鎖反應
工程 · 1 min read

GIF 編碼器合併相同影格是合法行為

看起來像影格遺失的東西,其實是規格允許的最佳化。符合規格的 GIF 編碼器可以合併連續相同的影格並加總 delay。

看起來像影格遺失的東西,其實是規格允許的最佳化。一個符合規格的 animated GIF 編碼器可以把連續相同的影格合併成一格,把 delay 加總到存活的那格上。總時長和渲染結果不變。只有影格數量下降。

輸入 f1 == f2 == f3 (synthetic,相同) f1 != f2 != f3 (真實動畫) cgif 編碼 寫入 3 格,合併重複 delay 加總 寫入 3 格 沒有可合併的 解碼 1 格 總時長不變 3 格 round-trip 完整
編碼器不管怎樣都寫入了每一格。log 可以證明。只有解碼結果不同。

注意中間那欄:編碼器不管怎樣都寫入了每一格。log 會顯示 cgifsave: N frames,即使解碼只讀到 1 格。如果編碼器真的在丟資料,這行 log 不該存在。

  • libvips 的 gifsave/cgifsave 預設就會這樣做:keep_duplicate_frames=FALSE,配合 interframe_maxerror 作為「夠接近就合併」的閾值。設 keep_duplicate_frames=TRUE 可以強制保留所有影格。
  • 真實的 animated GIF 每格都不同,所以 round-trip N 進 / N 出。只有全部相同的 synthetic 輸入會坍縮。
  • 測試裡的影格數斷言必須使用每格不同的 fixture(測試用的輸入檔案),否則你斷言的是編碼器有權改變的輸出。

你的影格沒有消失。編碼器合法地合併了它們。測試輸入才是問題,不是編碼器。


參考來源:

延伸閱讀: 回到連鎖反應總覽,或參見被污染的測試基準會反轉你的診斷和測試結果只是關於輸入的事實。

↑↓ 移動 ↵ 開啟 esc 關閉