两个RGBA四通道颜色的叠加计算方法与代码实现
疊加算法原理:
通過一些簡單的實驗外加一些邏輯推理,可以成功的找到 Alpha 混合的方法。這里為了計算上的方便,全部顏色分量值的取值范圍都是 0 ~ 1。
首先是透明度值的計算。顏色在本質上是光的產物,假設把透明度理解為玻璃的透光性,則一切就變得很easy。比如一個 alpha = 0.2 的顏色,就能夠將其想像為透光率為 80% 的彩色玻璃。我們透過這塊玻璃看去,因為 80% 的光都透過了,因此留下來的顏色僅僅剩 20%,即所謂 0.2 的 alpha。如今我們來做一個混合:將 alpha 為 0.2 和 0.6 的顏色進行疊加。這時,我們有了兩塊玻璃,一塊透光率為 80%,還有一塊為 40%。一道光束穿過,經過 80% 透光率的玻璃時,光線強度剩下 80%,再經過 40% 透光率的玻璃時,光線進一步被削弱,僅僅剩下 80% * 40% = 32%。這意味著有 32% 的透明性,即 alpha = 0.68。
總結上面的算法,我們能夠得出:
下一步,是依據(jù)已有的透明度來計算每一個通道的顏色分量。這其有用數(shù)學推導的方法更easy一些。我們已經知道,在背景色上怎樣疊加半透明色,其 RGB 顏色分量的計算方法為:
那么,我們能夠通過在背景色上疊加兩個半透明顏色的不同方法來進行公式推導。第一種疊加方式:先在背景色上疊上第一個半透明顏色,再在疊好的結果上疊上第二個半透明顏色;另外一種方式則是先將兩個半透明顏色疊好,再與背景色混合。即:
這兩種混合方式的結果應當是全然一致的,則有
整理,得
這即是 RGB 模式下的 Alpha 混合公式。對于 CMYK 等其它模式,也能夠用類似的方式推導。
代碼實現(xiàn):
class CColor { public:CColor(unsigned char a, unsigned char r, unsigned char g, unsigned char b){m_alph = a;m_red = r;m_green = g;m_blue = b;}// others... private:unsigned char m_alph;unsigned char m_red;unsigned char m_green;unsigned char m_blue; }float crCalculateBlend(float a1, float a2, float c1, float c2) {return (c1 * a1 * (1.0 - a2) + c2 * a2) / (a1 + a2 - a1 * a2); }const CColor crColorBlend(const CColor& cor1, const CColor& cor2) {float fAlp1 = cor1.GetAlpha() / 255.0;float fAlp2 = cor2.GetAlpha() / 255.0;float fAlpBlend = fAlp1 + fAlp2 - fAlp1 * fAlp2;float fRed1 = cor1.GetRed() / 255.0;float fRed2 = cor2.GetRed() / 255.0;float fRedBlend = crCalculateBlend(fAlp1, fAlp2, fRed1, fRed2);float fGreen1 = cor1.GetGreen() / 255.0;float fGreen2 = cor2.GetGreen() / 255.0;float fGreenBlend = crCalculateBlend(fAlp1, fAlp2, fGreen1, fGreen2);float fBlue1 = cor1.GetBlue() / 255.0;float fBlue2 = cor2.GetBlue() / 255.0;float fBlueBlend = crCalculateBlend(fAlp1, fAlp2, fBlue1, fBlue2);return CColor(fAlpBlend * 255, fRedBlend * 255, fGreenBlend * 255, fBlueBlend * 255); } 更多通道混合算法總結
以上是生活随笔為你收集整理的两个RGBA四通道颜色的叠加计算方法与代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 20年研发管理经验谈(十四)
- 下一篇: 零点城市社交电商2.1.7.4 VUE全