為 PNG 加上背景,意思是使用 alpha 合成公式 result_RGB = source_RGB × source_alpha + background_RGB × (1 − source_alpha),將每個透明以及半透明的像素取代為選定的單一實心顏色,然後將結果以與來源完全相同像素尺寸的全不透明 PNG 寫入。這個單一操作可以解釋讀者常感到好奇的三種行為:完全透明的像素會變成精確的選定顏色、完全不透明的像素保持不變,而半透明的像素則會依照其 alpha 值進行混色。柔邊、陰影、毛髮以及抗鋸齒文字之所以能在變更後保持完整,是因為新背景會以數學方式混合進每個半透明像素中,而不僅僅是墊在完全透明的像素下方。為 PNG 加上背景會在瀏覽器本地端執行這個精確的操作,解碼一個 PNG,將每個像素合成在選定顏色之上,並匯出一個尺寸相同的全不透明 PNG。來源檔案永遠不會被修改,操作過程也不會將任何內容上傳到伺服器,而下載的檔案會加上 `-background` 檔名後綴,方便與原始的透明版本區分。

add background to png explained
add background to png explained

「為 PNG 加上背景」實際上代表什麼

PNG 檔案可以攜帶第四個通道,稱為 alpha,用來記錄每個像素的透明度。alpha 值為 255 代表完全不透明,alpha 值為 0 代表完全透明,介於兩者之間的任何數值則是半透明像素,會與其後方的內容進行混色。當檔案單獨開啟時,影像檢視器會在透明區域顯示棋盤格圖案,因為那些區域並沒有儲存真實的顏色,只是一個讓背景顯示出來的指令。許多目的地並不會理會這個指令。商品上架範本、列印的 PDF、社群個人圖片上傳工具、投影片母版,或是收件匣預覽,可能會直接忽略 alpha,將完全透明的像素視為亮色的預設顏色,導致透明的標誌突然出現在白色或米色色塊上,而無法與預期的背景融合。

加上背景代表由你自己承擔那塊缺失的背景責任。你選擇一種實心顏色,工具會將該精確顏色寫入每個透明像素,而半透明像素則會接收其現有顏色與新顏色的加權混色結果。最終會得到一個沒有 alpha 的普通 PNG,任何程式都能開啟,不需要猜測影像後方應該顯示什麼。這類操作有時稱為壓平(flattening),有時稱為不透明化(opacifying),也有時稱為烘焙背景(baking in a background)。用詞不盡相同,但背後的數學原理都與下一節所描述的相同。

為何透明度必須進行合成,而不是單純塗覆

天真的做法是將選定顏色塗進每個 alpha 為零的像素,這會讓柔邊看起來破碎。抗鋸齒文字、毛髮絲、圓角圖示、陰影,以及羽化的商品去背圖,全都依賴介於 0 到 255 之間的廣泛 alpha 值範圍。如果只取代 alpha 為零的像素,半透明像素仍然帶有原本的顏色,在視覺上仍與匯出時所預設的背景綁在一起。新背景此時只會部分位於影像後方,因而留下淡淡的外框或色偏。

正確的操作是對不透明背景進行 source-over 合成。針對每個解碼後的 RGBA 像素,來源顏色會乘以其 alpha 值,選定的背景顏色則乘以 1 減去該 alpha 值。這兩項貢獻會相加,以一般 8 位元整數四捨五入,然後將輸出的 alpha 設為 255。這是 W3C 合成與混合規範 中所記載的標準公式,稱為簡單 alpha 合成,也是當你將影像繪製在實心填色上時,HTML 元素所套用的同一個公式。

三個特殊情況讓這個公式的行為符合直覺。完全不透明的來源像素(alpha 為 255)會讓選定背景的貢獻為零,因此來源顏色原封不動地通過。完全透明的像素(alpha 為 0)則會讓來源貢獻為零,因此選定背景原封不動地通過。alpha 約略為一半的像素會產生來源與背景幾乎均勻的混色結果。介於其間的所有數值則會產生讓柔邊在新背景下看起來正確的平滑混色。

來源 alpha來源貢獻背景貢獻在選定顏色上的結果
255(完全不透明)來源顏色的 100%0%來源顏色原封不動地通過
128(約一半)來源顏色約 50.2%約 49.8%接近均勻混色,略微偏來源
1(最低非零值)幾乎為零幾乎 100%幾乎等同於選定背景
0(完全透明)0%100%精確的選定背景顏色

實際範例:半透明紅色疊在藍色上

取一個來源像素,其紅色為 255、綠色為 0、藍色為 0,alpha 為 128(滿分 255),然後將其合成在純藍色選定背景上,即紅色 0、綠色 0、藍色 255。alpha 128/255 等於 128 除以 255,大約為 0.502。將公式 result = source × alpha + background × (1 − alpha) 套用於紅色通道,可得 255 × (128 ÷ 255) + 0 × (127 ÷ 255) = 128 + 0 = 128。綠色通道仍為 0,因為來源與背景的綠色皆為 0。藍色通道為 0 × (128 ÷ 255) + 255 × (127 ÷ 255) = 0 + 127 = 127。輸出為紅色 128、綠色 0、藍色 127,新 alpha 設為 255,視覺上呈現一個略偏紅色的深紫色。

這個細微的偏移正是你將半透明紅色標誌舉在純藍背景前時會看到的結果,因為 alpha 128 在 0 到 255 的範圍中,只略高於正中間。同樣的公式也能不費力地解釋其他邊界情況。alpha 為 255 的來源像素,其紅色 255、綠色 0、藍色 0 保持不變,因為背景貢獻乘以零。alpha 為 0 的來源像素會變成紅色 0、綠色 0、藍色 255,也就是精確的選定背景顏色,因為來源貢獻乘以零。公式中沒有任何近似值或門檻值,這也是為什麼這個工具在抗鋸齒文字、陰影以及羽化去背圖上都能表現得可預期。

如何在瀏覽器中為 PNG 加上背景

  1. 在新分頁中開啟「為 PNG 加上背景」,選擇你想要壓平處理的透明或半透明 PNG。工具在解碼前接受上限 25 MiB 的 PNG,且來源檔案在整個操作過程中都保留在你的裝置上。
  2. 使用瀏覽器的顏色選擇器選定實心背景顏色。請使用符合實際目的地的六位數 HEX 值,例如市集與文件使用純白色、個人圖片使用品牌色,或投影片母版使用範本背景。
  3. 選擇「Add background」。工具會解碼 PNG,使用前述公式將每個像素合成在選定顏色上,並在頁面上顯示結果不透明影像的預覽,連同其精確的像素寬度、高度以及產生的檔案大小。
  4. 以正常檢視大小檢視預覽。請特別留意柔邊、陰影,以及任何毛髮或羽化區域,因為這些區域最能受益於真正的合成,而不是簡單的 alpha 為零像素取代。
  5. 下載壓平後的 PNG。檔名會加上 `-background` 後綴,讓原始的透明來源檔案在後續比較或還原時仍然容易辨識。

輸出格式、限制以及工具不會做的事

下載的 PNG 保留來源的精確像素尺寸。工具不會裁切、調整大小、銳化、降噪,也沒有設定特定的檔案大小目標,因為這些變更都會以使用者未要求的方式改變影像的幾何結構。輸出的 alpha 通道也會在所有位置設為 255,因此它是一個真正的不透明 PNG,而非仍依賴透明度的 PNG。頁面上的預覽是透過暫時的本機 Object URL 產生,當影像變更或分頁關閉時便會立即釋放。

兩項操作限制讓瀏覽器保持流暢。解碼後的像素緩衝區上限為 16 megapixels,任一邊長上限為 12,000 像素。解碼前可接受 25 MiB 以內的檔案,而副檔名為 PNG 但位元組無效的檔案會產生明確的解碼錯誤,而不是顯示破損的影像。工具只接受 PNG,因為透明度正是這個工作流程的目的。JPEG 不攜帶 alpha 通道,而其他瀏覽器可解碼的格式在透明度與中繼資料行為上,於不同應用程式之間可能不一致。維持狹窄的輸入規範,才能讓輸出保持可預期。

如果目的地需要不同尺寸,請先加上背景,再用 Image Resizer 調整結果大小。如果目的地需要 JPEG,請先下載不透明 PNG,再用 PNG to JPG 進行轉換。將這些操作分開處理,可以讓每個結果都容易驗證,並避免背景變更在不知情的情況下改變檔案的幾何結構或失真品質。

加上背景之後:選擇正確的目的地顏色

這項技術已有明確定義,但視覺結果仍取決於選擇實用的顏色。白色是市集上架、文件內嵌以及大多數電子郵件用戶端的安全預設值,但在深色介面上看起來會過於刺眼。社群圖形、深色模式應用程式、印刷版面以及品牌系統,可能需要特定的 HEX 值,而不是從棋盤格預覽推測而得。下載後,請在實際目的地環境中以正常檢視大小開啟壓平後的 PNG,觀察柔邊與陰影,因為這些區域最能清楚顯示混色結果。這個工具會產生技術上定義明確的合成結果,但它不會認證品牌合規性、印刷色彩匹配、市集接受規則或無障礙對比,因此這些檢查在發布前仍須由人工完成。

如需深入了解,請參閱 如何將 GIF 分割成個別 PNG 影格

如需深入了解,請參閱 如何將影像切割成 PNG 方格圖塊