iT邦幫忙

2026 iThome 鐵人賽

DAY 24
0
AI 自動化

我以為我保留了五道閘門系列 第 24

Day 24|12 分鐘六筆 commit,只為了把一行字置中

  • 分享至 

  • xImage
  •  

模組五|發布與衍生物(Day 23–27)

昨天講封面套版,收在「排版要交給程式」。今天講程式排版出錯的那一次。

它很小。小到我原本沒打算寫。而它的 commit 序列太乾淨了,乾淨到可以當教材。

六筆,12 分鐘

14:06  調整視覺樣式
14:08  重新設計卡片
14:11  更換圖片
14:14  修正文字對齊
14:14  修正文字對齊
14:18  以 textbbox 動態置中並重新產生
14:18  以 textbbox 動態置中並重新產生

問題是:導流卡上一行英文標籤沒有置中。

前四筆在猜座標。第五、六筆換了做法。

前四筆為什麼失敗

我伸長手臂憑目測往牆中線貼字條,牆上已經有四張都貼歪了

猜座標的寫法大概是這樣:

# 硬寫:假設這行字大約 200 像素寬
draw.text((W // 2 - 100, y), label, font=font)

那個 100 是估的。而它會在四種情況下失效:

  • 換字串(長度不同)
  • 換字級
  • 換字型
  • 中文與英文混排

最後一個最麻煩:中文字寬度跟 len(text) 沒有可靠關係。一個全形字約等於兩個半形字,但標點、數字、可變字重的拉丁字母全部不一樣。

所以「數字元個數再乘一個係數」這條路,在中文排版上從一開始就是錯的。

而我試了四次。

第五筆換了做法

我先用兩塊木夾把字條夾到剛好貼合,再照著夾出來的寬度放上去

bbox = draw.textbbox((0, 0), label, font=font)
text_w = bbox[2] - bbox[0]
draw.text(((W - text_w) / 2, y), label, font=font)

textbbox 是量出來的。 它把這個字串、用這個字型、在這個字級下實際會佔多寬算給你。

換字串、換字型、換字級,全部自動正確。

從「假設它多寬」變成「問它多寬」。這是一行的差別,而它讓這個 bug 從「每次改文案都要重調」變成「不會再發生」。

這跟 Day 21 是同一件事

三天前講多軌時鐘漂移,最後的解法是:放棄求一條全域曲線,改成在每個剪點各量一次。

今天的解法是:放棄估算文字寬度,改成在每次繪製時量一次。

同一個心法,不同尺度:量測比計算可靠

而兩次的失敗模式也一樣:我都先試著找一個「規律」(一個常數平移、一個字寬係數),失敗了幾次,才回到「直接量」。

為什麼會有這個傾向?我想是因為計算看起來比較聰明。找到一個公式感覺像是理解了問題;而每次都去量一次感覺像是放棄了理解。

但在這兩個案例裡,「每次量一次」才是正確的理解:它承認了那個量本來就是隨情境變的。

這個坑只踩了一次,但踩得很深

我 grep 了全 repo 的排版、對齊、字型相關 commit:總共只有 11 筆,而其中 4 筆集中在這 12 分鐘。

另外兩筆字型相關的 commit 是不同時期的,而成因一模一樣:產圖腳本找不到字型檔,或算不準文字寬度。

也就是說:這一族問題總共佔了全 repo 排版類 commit 的一半以上,而它們全部來自同一個根因

textbbox 之後,這一族問題就沒有再出現過。

順帶:影片編碼參數的雜訊

既然講到產出,把影片那邊的參數也攤開,它比封面亂:

腳本 fps audio bitrate
直式主渲染器 30 192k
橫式輸出 1 320k
直式(另一支) 1 192k
又另一支 2 192k

四種 framerate、兩種 audio bitrate。

fps 的差異其實有道理:一張靜態圖配音訊,用 1 fps 可以把檔案壓得很小。而 30 fps 那支是因為有動態元素。

但 1 / 2 / 30 三個值並存,代表沒有人決定過「靜態影片該用幾 fps」,只是每次隨手寫。

-crf 更誇張:全 repo 只設過一次(值是 20),其餘全部走 x264 預設。

這些不會出事,但它們是 Day 23 那個「沒有 design token」在影片端的版本:每一個參數都是某一次隨手決定的,然後被複製下去。

一個統計陷阱,順便修正我自己

看那六筆 commit 的時候,我發現一件事:

14:14 那兩筆的 diffstat 完全相同(3 個檔案、17 行新增、6 行刪除)。14:18 那兩筆也一樣。

不是我改了兩次同樣的東西,是同一份變更被兩套 commit 訊息各記了一次,來自平行分支後的合併。

這件事有統計上的後果:

git rev-list --count HEAD                 →  1,180
git rev-list --count --first-parent HEAD  →    995
merge commits                             →     32

約 185 筆是從側枝併進來的雙記。

所以 Day 1 我說「兩個 repo 加起來 1,513 個 commit」,那個數字用的是 first-parent(995 + 285),是對的。但如果直接用 rev-list --count,會得到一個灌水 18% 的數字。

談工作量要用 first-parent。 這條我寫進了這個系列的數字口徑表,而且發布前檢查腳本會擋。如果哪一篇寫了未經修正的那個數字,它會噴錯。

代價

這一篇的內容太小了。

一個置中的 bug,六筆 commit,12 分鐘。它撐不起一整天,如果不是因為它剛好示範了跟 Day 21 一樣的心法,我會把它併掉。

而我留著它,是因為小 bug 的 commit 序列比大事故乾淨:大事故的紀錄裡混雜太多東西,這個只有一條線。

第二個代價,比較實際:那四種 fps 跟兩種 bitrate 我沒有統一。 它們不會出事,所以永遠排在待辦的最後面。而它們正在讓「這個節目的影片」變成四種不同的東西。

帶走什麼

量測比計算可靠。

任何「算出來的位置、大小、偏移量」,在輸入變化的時候都會錯。而「量出來的」不會。

具體的判斷方法:如果你在寫一個係數或魔術數字來估算某個量,先問:這個量能不能直接問出來?

  • 文字寬度 → textbbox
  • 音訊的靜音位置 → silencedetect
  • 元素的實際尺寸 → 量它,不要算它

第二條,關於為什麼我們傾向計算:

找到公式感覺像理解了問題,每次都量感覺像放棄理解。 而在「那個量本來就隨情境變」的情況下,每次量一次才是正確的理解。

判斷標準:這個量有沒有一個穩定的規律? 有,用公式;沒有或不確定,量它。而「不確定」的時候選量,因為量的成本通常很低,猜錯的成本很高。

第三條,統計上的:

git rev-list --count 會把側枝的重複記錄算進去。 談工作量、談節奏、談「這個專案多活躍」的時候,用 --first-parent我的差距是 18%,而 18% 足以讓一個論點站不住。

明天講一件比排版難堪得多的事:發布文案裡,有節目從來沒講過的話。


上一篇
Day 23|五十張封面,只有兩張是 AI 畫的
下一篇
Day 25|短影片有流量,但它沒有回到正片
系列文
我以為我保留了五道閘門25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言