2016-11-24 63 views
3

我在Direct2D中繪製位圖。位圖使用透明度(alpha通道)。Direct2D - 如何用位圖做伽馬校正透明(alpha)

混合看起來不對。

作爲一項測試,我加載了50%透明度的純黑色PNG圖像,並將其繪製在白色背景上。結果是紅色,綠色和藍色值爲127(0x7F7F7F)的像素。這表明Direct2D的融合忽略了伽瑪,並將色彩值視爲線性。

(位圖使用常規sRGB色彩空間,每像素32位,紅色,綠色,藍色和Alpha各8位)。它們以GUID_WICPixelFormat32bppPBGRA格式加載。

在sRGB中,黑白之間的混合是186(0xBABABA)。這是我想要的理想結果。

Direct2D可以顯示透明度嗎?我會怎麼做?任何幫助讚賞。

Direct2D vs Gamma-correct blend

+0

我想你已經倒退了。在sRGB中,50%會看起來像黑色和白色之間的中途(亮度,挺)。它看起來太亮還是太暗?這可能是由於它顯示的方式。 –

+0

我的理解是sRGB色彩空間定義了像素強度與實際存儲數之間的非線性轉換。即伽瑪曲線。 例如,一個8位顏色值的範圍爲0-255,但由於伽馬曲線的原因,在大約20%的亮度下顯示值127(半途)。 因此,伽瑪校正50%黑白混合的像素值應爲186(滿量程的73%)。所以在Direct2d中,我的混合看起來太黑了。 –

+0

@astraycat如果您查看交替的黑白像素並將它們與固體塊進行比較,則BABABA塊在正確校準的顯示器上應該具有相同的亮度。即使在未校準的顯示器上,BABABA也應該比7F7F7F更接近。 –

回答

1

混合以線性色彩空間處理得當,因此對於混合的sRGB像素的過程中,應

  1. 轉換成線性
  2. 混合
  3. 轉換回sRGB的。

請注意,對於黑色或白色像素,步驟(1)和(3)是空操作,可以省略。

查看PNG規範的alpha channel processing部分。特別要注意的是:

用於計算合成樣品值的公式是

output = alpha * foreground + (1-alpha) * background

其中α值與輸入和輸出的採樣值是 表示爲範圍爲0的級分這個計算應該是 用強度樣本(非伽瑪編碼樣本)執行

該部分包含用於alpha通道處理的樣本C代碼

在提出此問題時,HWND Render目標(繪圖到屏幕)不支持線性像素格式;但是,Direct-2D HwndRender目標現在已被接口ID2D1DeviceContext取代。這些通過IDXGIFactory2::CreateSwapChainForHwnd()創建,並支持更多像素格式,如DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,它可在混合時自動執行正確的色彩空間轉換(信息由@Jeff McClintock提供)。

+0

乾杯,這是有道理的(在線性顏色空間中執行混合),但是如何在Direct2D中實現? (也許渲染目標和位圖需要設置爲特定的像素格式?)。 –

+1

我做了一些研究。 AFAIK Direct2D HWND渲染目標(繪製到屏幕)不支持線性像素格式,並且如果將位圖轉換爲線性格式,則不再支持硬件加速(Direct2D的主要優勢)。 DIrect3D(Direct2D基於此)確實支持位圖上的操作,從而將像素轉換爲線性色彩空間並在混合操作期間返回。可惜Direct2D不支持這個。 –

+0

更新:Direct-2D HwndRender目標已被接口\t \t ID2D1DeviceContext取代。這些通過IDXGIFactory2 :: CreateSwapChainForHwnd()創建,並支持更多像素格式,如DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,它可在混合時自動執行正確的色彩空間轉換。 –

0

Direct-2D 1.0 HwndRenderTarget直接對像素值執行混合計算。這會導致使用alpha通道合成標準sRGB圖像的錯誤。該錯誤是因爲Direct 2D將伽瑪壓縮強度值視爲線性強度值。

忽略gamma會導致合成質量差,幾何抗鋸齒,圖像大小調整和文本呈現。

有一種解決方法,它是「預先扭曲」位圖的alpha值以補償混合計算引入的錯誤。

示例: 左圖是通過在線性色彩空間中執行混合來正確合成的,中心圖像是Direct 2D(陰影太暗和'contrasty'),右邊的圖像是預彎曲Alpha通道後的Direct2D。

Direct 2D Renders alpha blends to dark and 'contrasty'

見:https://bel.fi/alankila/lcd/alpcor.html

UPDATE!:較新版本的直接-2D(1.1)的支持它們執行正確共混SRGB背緩衝器。使用IDXGIFactory2 :: CreateSwapChainForHwnd()來使用改進的顏色深度選項。