Skip to content
All writing Part 07 of 07 · 裁切、縮放、填滿:圖片處理
Engineering · 1 min read

均勻變換 vs 定位變換:在拼接長條上的差別

一個變換能不能直接對整條 libvips page-strip 做,只看一個問題:它在乎座標嗎?均勻變換整條做安全,定位變換必須逐格處理。

一張 GIF 在 libvips 裡是一條「上下疊起來的長條」(page-strip):5 格 × 100px = 一張 500px 的圖。一個變換能不能直接對這條長條做,取決於一個問題:它在乎像素在哪裡嗎?

  • 均勻(uniform) = 每個像素同一套規則、跟位置無關 → resize/scale。縮整條,每格一起縮、邊界對齊,還是一段合法動畫,它根本不用知道有影格這回事。
  • 定位(positional) = 針對特定座標或區域下手 → crop、fill/pad。在長條上那個座標指到的是「一疊影格」,不是「每格的同一個位置」,一個天真的框切下去就跨過影格邊界,變成垃圾。
均勻 · resize — 安全 f0 f1 f2 f3 f4 每格一起縮放 → 動畫存活 定位 · crop — 壞掉 f0 裁切框跨過影格邊界 → frame 1–4 消失 = 垃圾
會看座標嗎?不會 → 均勻,整條一起做。會 → 定位,逐格處理。

定位操作的修法:[n=-1] 載入、依 page-height 把長條拆成每一格、每格套一模一樣的操作、vips_arrayjoin(across=1) 接回去,最後把 page-heightn-pagesdelay 補回去。

判斷口訣: 對整張一視同仁地縮放、改色 → 均勻 → 整條做沒問題;針對座標或區域 → 定位 → 乖乖逐格處理。我手上的服務就是這樣分:純 resize 對整條長條跑,crop 跟 fill 逐格跑。

跟語言無關: vips_* 是 libvips 的 C API 名字,但這條幾何規則在任何 binding(govips、pyvips、sharp)都成立,換語言也不會變。

會不會看座標,決定了你能整條做、還是得逐格做。


參考來源:

Related: 這一篇收束了libvips 把動圖存成一條上下疊起來的長條一條載入路徑,同時吃靜圖與動圖,或回到裁切、縮放、填滿的四堂課總覽

Tags #image-processing #libvips
// connect

Be brave | Be wise | Be grateful

21 BreakinCode

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