Skip to content
All writing Part 05 of 09 · 一次 Golang 版本升級的連鎖反應
Engineering · 1 min read

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

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

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

輸入 cgif 編碼 解碼 f1 == f2 == f3 (synthetic,相同) 寫入 3 格,合併重複 delay 加總 1 格 總時長不變 f1 != f2 != f3 (真實動畫) 寫入 3 格 沒有可合併的 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(測試用的輸入檔案),否則你斷言的是編碼器有權改變的輸出。

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


參考來源:

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

Tags #devops #debugging #docker
// connect

Be brave | Be wise | Be grateful

21 BreakinCode

// elsewhere
LinkedInMedium (lang: en)Youtube
wh:~$William Hung· © 2026 Taipei · GMT+8 · Available for collaboration