九筆 commit 裡有四筆在改掉自己前面寫過的東西
9 月 1 日做的簡報背景圖研究。配方抓錯集數、逾時原因沒定位、修好兩個真 bug 卻誤診死因、一個數字只抽樣就寫上去,四次的翻法都不一樣。方法是別人影片裡的,數字是自己跑出來的。

9 月 1 日一整天,這個 repo 進了八筆 commit,隔天凌晨再一筆。九筆裡有四筆在改掉前面已經寫上去的東西:一次是配方抓錯集數,兩次是同一個逾時原因改了又改,還有一次是數字只抽樣就填上去。四次的翻法都不一樣。
這個 repo 裡的量測腳本、生圖、頁面文字都是 AI 做的,四筆修改也是 AI 動的手。我做的是要它做什麼、看哪裡不對、要它再去查一次、拍板。
題目只有一句話:一張 AI 生的背景圖好不好看,跟它能不能拿來當簡報封面,是兩件事。
這份研究跟隔天那場週三直播是同一條線。9 月 2 日晚上要講怎麼做高質感的網頁簡報,籌備記錄把這份研究列在「相關的新素材(這週做的,可在 QA 拿出來用)」底下(那場直播自己的故事在我抓到簡報上一個錯的數字,只改了一半,上台照著大字唸了出來)。方法拆自 YouTube 頻道「大师的AI小灶」的第 3、4 集,以及同一位作者的兩份飛書文件。
先有一把尺
要比背景圖能不能用,得先有個量法。
experiments/verify.py 把畫面切成六塊候選文字區,位置是九宮格的外圈,避開正中央,每塊佔畫面寬 44%、高 30%。每塊量兩件事:亮度標準差要小於 0.12,白字或黑字至少一種的 WCAG 對比度要大於 5.0。兩項都過算一塊可用,寫成「幾 / 6」。
門檻訂 5.0 的理由寫在檔頭:任何平坦色塊都過得了 WCAG 的 4.5,那條線擋不住東西。工具自己也有負控制,verify.py --self-check 會確認純黑圖六塊全過、隨機雜訊圖一塊都不過、亮度落在中間的死區不過、中灰以黑字過關。這次重跑,四條斷言都還在。
這把尺只在第一次翻案派上用場。Veo 那兩次跟它無關,靠的是讀 log 與重跑。
第一次:配方抓錯了集數
第一輪六張圖,三組 A/B,每組只動一個變數:比提示詞寫法、比尺度、比光。圖交回來是風景攝影的長相。我看了問它是不是沒抓到重點,原片裡的背景沒有它生的那麼普通。
回去重看原片才對出原因。第 3 集講紀實攝影,案例是飛機、貨輪、燈塔、衝浪者。第 4 集講深色超現實概念藝術,示範畫面是銀河、巨型星球、書頁上加班的太空人,沒有一張是攝影。第一輪拿的是第 3 集文件版那張提示詞塊對照表,做的卻是第 4 集的技巧。兩集的視覺語言不同,那張表在這裡混用不了。
第 4 集的影片畫面上直接打出了完整提示詞。把 1280×720 的原幀放大三倍逐字讀回來,拆成六段:
- 前景與遠景分開寫
- 主體極小,環境極大
- 留白寫成深藍到黑的暗場
- 主體亮度明顯高於環境
- 冷色調加高對比
- 風格詞收尾
最容易漏掉的是暗場那一條,站上寫的是多數人會直覺去做亮天空。
照配方重做四張,量出來的差距:
| 代表區對比 | 平坦度 | |
|---|---|---|
| 第一輪六張 | 5.25 到 13.61 | 0.0339 到 0.1198 |
| 第二輪四張 | 14.39 到 20.66 | 0.0003 到 0.0570 |
封面那兩張就是同一個題材的前後。左邊是攝影風的黃昏帆船,右邊是銀河中心那艘被暖金光照亮的小帆船。
第二次:逾時的原因空著
背景還要能動起來。我問它有沒有辦法產生動態背景,手上能用的是 Veo,它掛在 gemini-web 底下,gemini-web 是自架在區網那台機器上、用程式操作 Gemini 網頁的服務。
結果頁第一版寫的是「文生影片實跑了兩次,第一次等了 728 秒逾時。所以 Veo 這條目前還沒拿到成品」。原因欄是空的。後來那筆翻案的 commit 訊息回頭把這個空白點名成一種歸因:「不是 Veo 慢」。
翻服務的 log,實跑其實是三次:728 秒、1448 秒、189 秒,全部逾時。log 寫著已經從側欄進入影片頁、找得到輸入框、「prompt 已送出,開始等待」。可是等滿之後,頁面上 document.querySelectorAll('video, source, [class*=media]') 回的是空陣列,三次都一樣。
逾時當下的截圖停在「建立影片」的範本牆,輸入框是灰色的 placeholder,對話串裡沒有任何使用者訊息。換成 37 個字元的最短提示詞,結果一模一樣,排除了提示詞太長。
那段字根本沒送進去,等多久都不會有影片。
當時寫下的結論是:服務的防呆判準錯了。它檢查的是「字還留在輸入框裡嗎」,留著就改點送出鈕。新介面上字沒有留著,防呆不觸發,程式就當作送出成功,然後空等到逾時。
第三次:修了兩個真的 bug,但那不是壞掉的原因
我記得前一天那台機器上的服務好像改過東西,叫它去看。結果翻出一份沒生效的修正。主檔 src/gemini.py 改了 268 行,另外多了兩支測試檔。這份修正 8 月 31 日 16 點 28 分才寫好,服務最後一次重啟是 16 點 18 分,所以它從來沒跑過。
它修的是兩個真的 bug:
- 檢查輸入框有沒有殘字時,
document.querySelector讀到的是 Quill 的隱藏貼上緩衝區,那裡永遠是空的。 - 送出鈕的
aria-label實際上是「傳送訊息」,舊寫法在中文介面一個都配不上。
把它 commit、開 PR、重啟服務讓它生效,第四次再跑:1448 秒,依然逾時,畫面跟前三次完全相同。
後來一筆 commit 把「查出來的原因」改寫成「查到哪裡為止」。目前指向的是那個落地頁本身:頁面上寫著「試用範本或在對話中描述想生成的影片」,而服務是在範本牆的輸入框打字。合理的推測是那個輸入框不是真正的送出入口。要確定得開真瀏覽器手動打一次字,那天沒做。
找到真的 bug、修好、看著它生效,每一步都對,合起來還是推出一個錯的結論。分辨的方法是修完再跑一次。
第四次:數字只抽樣就寫上去
隔天凌晨那筆動的是另一頁,開源網頁簡報的生態盤點。那頁原本寫 dashi-ppt-skill(一個產 HTML 簡報的 skill)的產物「只帶其中一支主題 runtime,約 0.7 MB」,還加了一句「單支介於 0.70 MB 到 0.77 MB 之間」。
那個區間是抽樣抽到最小的兩支。project/dist/theme-runtime/ 底下有十二支 imported-theme-runtime.themeNN.js,最小 696,202 位元組,最大 1,308,738 位元組。這幾個數字這次重新數過。
那筆 commit 改成實測值:實際匯出的成品整包 8.2 MB,字型 4.6 MB、runtime 1.3 MB。
前三次是原因或配方抓錯,這一筆是數字只量了抽到的兩支。
自己量到的那一側
方法是別人的,數字是自己跑的。verify-result.json 裡有 21 筆:二十張生成圖,加一張著色器的截圖。(站上那兩處寫的是「十九張」,這次逐筆數是二十張,以這裡為準。)圖全部走本機 Codex CLI 的 $imagegen,吃 ChatGPT 訂閱額度,做法寫在用 Codex CLI 的 $imagegen 在 Claude Code 裡生圖。
三招各自的代價,每組只動一個變數:
| 對照組 | 前 | 後 | 代價 |
|---|---|---|---|
| 提示詞四段結構 | 一句話 1 / 6 | 四段 3 / 6 | 沒有 |
| 尺度失衡 | 正常尺度 4 / 6 | 失衡 3 / 6 | 少一塊 |
| 加發光元素 | 平光 6 / 6,對比 10.53 | 加光 6 / 6,對比 13.61 | 沒有 |
中間那一列是來源影片沒講的。風暴眼裡那艘小帆船張力很強,但風暴雲填滿了整個畫面,夠平坦的只剩右下那塊暗角。要用這一招,就得接受標題只有一個位置放得下。可放字區的多寡跟畫面好不好看是兩回事。
另外四件也量了:
- 隨機性。同一組提示詞原封不動跑三次,馬的位置、沙丘形狀、鏡頭高度每次都變,可放字區三次都是 6 / 6。構圖每次都變,可用性沒變。
- 配色。換發光顏色,青綠、洋紅、翠綠,加上原本的暖金,四色全部 6 / 6,前提是結構一字不動。嚴格說環境色詞也跟著換了,不只動一個變數。
- 用程式畫背景。一支純 WebGL 的 fragment shader,沒引用任何函式庫,6 / 6、對比 20.30、平坦度 0.0004。這個平坦度不是全場最好的,二十張生圖裡有六張比它更平。它的好處寫在站上:檔案大小是零、任意解析度、本身就在連續旋轉。代價是畫不出具象主體,只做得了抽象的光與結構。
- 修圖三步。原片示範用的是豆包的內建擦除與擴圖,這裡換成 Codex CLI 的 image-edit 跑同一套。可放字區 2 / 6 修到 4 / 6,換天氣那一步幅度最大。去干擾沒做乾淨,右側那根電線桿三步都還在。擴留白那步變成整張重畫,天空變多是重新構圖的副作用。
讓背景動起來那條走的是 ffmpeg。zoompan 的運鏡參數全部寫成 1-cos(2*PI*on/N) 的形式,第一幀跟最後一幀的值相同,循環播放不會跳。
12 秒 288 幀,抽第 0 幀與第 287 幀逐像素比對,沙丘那支平均色差 0.458,銀河那支 2.89(滿分 255)。站上當時記的是 0.46 與 2.54,後面那個數字這次沒有重現。代價是只做得出推近與平移,一張平面圖沒有深度資訊,繞不過去。
沒驗的也列在站上:二十張圖全部走同一個模型,換一家會怎樣不知道;四段結構與尺度失衡各只有一張對一張,沒有重複樣本;圖生影片一次都沒成功;用程式當背景那一節列了八條前端的路,只實作了著色器這一條。
為什麼公開的 repo 裡沒有原始材料
逐字稿與飛書文件是別人的內容,故意不進公開 repo,只留在本機。所以站上點不到原文,只有 YouTube 與飛書的來源連結,方法一律用自己的話轉述。
兩支影片都沒有字幕軌,逐字稿是本機跑 whisper large-v3-turbo 轉的,會有辨識誤差;文件版照原文整理。兩邊對得起來的部分才寫進去。
自己去看
筆記主頁在 https://yazelin.github.io/slide-background-research/。同一句標題壓在十張背景上的對照實驗投影片在 https://yazelin.github.io/slide-background-research/demo/,按 G 會把六個候選區與量測數字疊上去。開源網頁簡報生態盤點另外一頁:https://yazelin.github.io/slide-background-research/ecosystem/。
上面的數字,量測腳本吐出來的那些這次都重跑對過;四次逾時的秒數、268 行、匯出成品 8.2 MB,是從 repo 的頁面與 commit 訊息讀出來的,沒有重跑。
後記(2026-09-12)
repo 停在 9 月 2 日凌晨那一筆,之後十天沒有再動。今天三個頁面都還開得起來。
Veo 那一步還是沒做,圖生影片到現在沒有成品,站上那一節的狀態仍然是卡點還沒定位。
9 月 6 日那份十月週三直播的選題單,把「簡報背景怎麼做」從投票選項拿掉了,理由是連結已經給過社群,不另開一場。那支著色器倒是被 9 月 30 日那場的籌備記錄挑走,當「自己寫也一條路」的例子。