Engineering · 1 min read
libvips 把動圖存成一條上下疊起來的長條
libvips 不把多影格圖片存成 N 張影格,而是疊成一條很高的 page-strip:每格上下堆疊,page-height、n-pages、delay 全記在 metadata 裡。
libvips 處理任何多影格圖片(animated GIF/WebP、multi-page TIFF/PDF)時,不是存成 N 張獨立影格,而是把每一格上下疊成一張很高的圖,官方叫 page-strip,我習慣想成一捲攤開的衛生紙。
- 結構藏在 metadata:
page-height(一格的高)、n-pages(幾格)、delay(每格毫秒)。恆等式:n-pages × page-height = 總高。 - 所以
imageRef.Height()回的是整條的高(全部影格加起來),而Pages() > 1就是「我手上是一條長條、不是一張靜圖」的旗標。
我原本猜這些影格尺寸各不相同,結果剛好相反:每格一模一樣大,正因為一樣大,libvips 才能整齊疊成一條。判斷是不是動圖,我就是用 Pages() > 1。
影格在長條裡的順序
影格由上往下、照播放順序疊:frame 0 在最上面(y = 0),下一格緊接在下面。把「衛生紙」從上往下攤開,拿到的是 frame 0→4,不是反過來。
top = i × page-height——要裁出一格就從這裡切。要抽第 i 格,就從 y = i × page-height 裁:frame 0 在 y=0、frame 4 在 y=4·ph。這也證明了它是由上往下、不是由下往上。
動圖在 libvips 眼裡是一張高圖,不是一疊影格。
參考來源:
Related: 這正是一條載入路徑,同時吃靜圖與動圖與均勻變換 vs 定位變換:在拼接長條上的差別成立的基礎,或回到裁切、縮放、填滿的四堂課總覽。