共用方式為


預乘 Alpha

在電腦圖形中,有兩種不同的方法來表示色彩值的不透明度。 這兩種方法 Win2D 都會使用。 本文說明之間的差異,以及各自使用的地方。

直接 Alpha

使用直接 (也稱為線性) Alpha 時:

  • RGB 值會指定所繪製項目的色彩
  • Alpha 值會指定其實心程度

在這個世界,RGB 和 Alpha 是獨立的。 您可以變更其中一個,而不會影響另一個。 若要讓物件淡出,您會逐漸減少其 Alpha 值,同時讓 RGB 保持不變。

若要在使用直接 Alpha 格式的兩種色彩之間執行來源混合:

result = (source.RGB * source.A) + (dest.RGB * (1 - source.A))

預乘 Alpha

使用預乘 Alpha 時:

  • RGB 會指定繪製的項目對輸出造成多少色彩
  • Alpha 值會指定它對其背後任何內容的遮蔽多寡

在這個世界,RGB 和 Alpha 是連結的。 若要使物件透明化,您必須減少其 RGB (貢獻較少色彩) 以及它的 Alpha (對它背後任何內容遮蔽較少)。 完全透明物件完全沒有任何色彩,因此只有一個值代表 100% 透明度:RGB 和 Alpha 全部為零。

若要在使用預乘 Alpha 格式的兩種色彩之間執行來源混合:

result = source.RGB + (dest.RGB * (1 - source.A))

預乘 Alpha 用於圖形轉譯,因為它在篩選影像或撰寫不同圖層時,可提供比直接 Alpha 更好的結果。 如需詳細資訊,請參閱下列文章:

Win2D 中的 Alpha

Win2D 在其 API 介面中使用直接 Alpha,但內部轉譯作業使用預乘 Alpha。

Windows.UI.Color 值使用直接 Alpha。 每當您將色彩傳遞至 Draw*Fill* 方法、設定筆刷色彩,或是清除設為某一色彩值時,就會使用直接 Alpha 指定此色彩。

儲存在點陣圖或轉譯目標中的像素值,以及在這些介面上運作的繪圖或混合作業,請使用預乘 Alpha。 從檔案載入點陣圖時,其內容會自動轉換成預乘格式。 當您呼叫 Win2D 繪圖方法時,其色彩參數會在實際繪圖發生之前,從直接轉換成預乘。

Win2D 影像效果使用直接和預乘 Alpha 的混合。 某些效果會針對一種格式運作,有些則針對另一種格式運作,有些則提供屬性可加以選擇。 每個效果類型的文件會描述其使用哪一種 Alpha 模式。 效果輸入資料一律會假設為預乘,因此當效果需要使用直接 Alpha 時,它會先套用非預乘的轉換、計算效果,然後重新預乘輸出。

點陣圖 API GetPixelBytesSetPixelBytesGetPixelColorsSetPixelColors不會執行任何 Alpha 格式轉換。 它們只會直接將位元值傳送到或傳送自基礎 GPU 紋理。 這可讓您觀察哪些 Alpha 格式 Win2D 在內部使用:

  • 在轉譯目標上建立繪圖工作階段
  • 呼叫 drawingSession.Clear(Colors.Tranparent)
  • Colors.Tranparent 定義為 R = 255、G = 255、B = 255、A = 0
  • Win2D 會將此值轉換成預乘格式,產生 R = 0、G = 0、B = 0、A = 0
  • 使用 GetPixelColors 讀回轉譯目標的內容
  • 觀察它包含預乘格式 RGB = 0,而不是 RGB = 255,就像原始的直接 Alpha Colors.Tranparent 值一樣

在 Alpha 格式之間轉換

若要將直接 Alpha 色彩值轉換成預乘格式,請將它的 R、G 和 B 值乘以 A。若要將預乘轉換成直接,則將 R、G 和 B 除以 A。

請注意,色彩資訊通常以位元組值表示,範圍從 0 到 255 (例如 Windows.UI.Color 結構包含 4 個位元組)。 這個表示法會以 255 的乘數增加,因此位元組的值 255 實際上表示 1,而 128 是半強度。 此縮放比例必須在格式轉換期間納入考慮,因此若要將 Windows.UI.Color 從直接轉換成預乘:

premultiplied.R = (byte)(straight.R * straight.A / 255);
premultiplied.G = (byte)(straight.G * straight.A / 255);
premultiplied.B = (byte)(straight.B * straight.A / 255);
premultiplied.A = straight.A;

如果您有使用錯誤 Alpha 格式的影像資料,PremultiplyEffectUnPremultiplyEffect 可用來轉換它。