大家可以在網上搜索相關的主題啊,你可以搜索到一堆,不過似乎沒有那一個講的很全面,我這里抽空整理和測驗一下資料,分享給大家,
我們假定有2個32位的圖層,圖層BG和圖層FG,其中圖層BG是背景層(位于下部),圖層FG是前景層(位于上部),我們摸索其混合后的顏色的計算公式,
我們取一個點的像素做分析:
其中BG層某點的顏色為: B1 = 168 G1 = 99 R1= 114 A1 = 70
其中FG層某點的顏色為: B2= 80 G2 = 71 R2= 162 A2 = 135
場景一:兩個圖層直接疊加
即混合模式為正常,前景的不透明度為100%,如下所示:

得到的混合結果為 B = 97 G = 76 R = 153 A = 168
注意這些資料的格式都是 Format32bppArgb,而非Format32bppPArgb,即沒有進行預乘的ARGB資料,
根據這些資料進行推算,得出以下規律,首先是結果色的A值計算公式如下:

其中ClampToByte函式的作用為限制括號內的資料在0和255之間,如果大于255,則取255,如果小于0,則取0值,
按照此公式復核下上面的結果看下:

結果正確,
對于RGB各分量,計算公式要復雜很多,經過推到和測驗結果如下(以B分量為例):

把資料帶入核算一下:

同理:

公式完全正確,
上面的計算如果要保證精度,則A值需要用浮點數保存,這樣可能在某些場合下造成計算瓶頸,如果要全部用整數運算,可利用用Matlab的符號運算在做簡化,
在matlab中用如下代碼做測驗:
syms B1 A1 B2 A2; B =( B1 * A1 + B2 * A2 - A1 * A2 / 255 * B1) / (A1 + A2 - A1 * A2 / 255); simplify(B)
得到結果:
B1 - (255*A2*(B1 - B2))/(255*A2 - A1*(A2 - 255))
這個結果只有一個除法,而且可以看到除法的分子和分母的資料也不會大于int32所能表達的范圍,這樣可借助于整數的除法實作結果,
場景二:僅僅改變圖層混合模式
我們僅僅改變前景色圖層的混合模式,而不改變其不透明度,以正片疊底模式為例,如下圖所示:

此時前述兩個顏色的混合值如下所示:
B = 91 G = 67 R = 133 A = 168
注意到A值并沒有任何的變化,
此時,我們定義一個函式F,表示混合模式對兩種的顏色影響,F(X, Y)表示某種混合模式下兩種顏色值X和Y的混合結果,對于正片疊底,F(X,Y)的計算方法為:
F(X,Y) = X * Y / 255;
經過測驗,這個時候的RGB分量的混合公式為:

把資料帶入核算一下:

G和R的值就不進行重復的核算了,
這個計算式用Maltab去簡化的話基本沒有任何效果,
場景三:僅僅改變圖層的不透明度
如下所示設定,前景層的不透明度為70%,

此時前述兩個顏色的混合值如下所示:
B = 108 G = 80 R = 147 A = 139
所有的顏色都變了,
還是先來看A值,經過測驗比對,此時A值的計算公式為:

其中O表示不透明度的值,有效范圍是[0,100],
核算一下:

對于A值,我們可以認為不透明度首先修改了改成的Alpha,然后再拿這個新的Alpha和底層的Alpha進行正常的混合,
對于RGB各分量,經過推到和測驗結果如下(以B分量為例):

核算一下:

正確無誤,
場景四:同時改變圖層混合模式和不透明度
如下所示設定,同時設定混合模式為正片疊底,不透明度為70%,

此時前述兩個顏色的混合值如下所示:
B = 103 G = 72 R = 130 A = 139
可以看到,A值和混合模式沒啥關系,之和不透明度有關,直接用只改變不透明度時的公式:

那么RGB的變化,從前面的幾個公式中可以猜測肯定是先下面這個式子了:

測驗下:

完全正確,
那么在寫代碼的時候,我們最需要優化的就是這個情況的公式,不過用matlab測驗這個公式沒啥好優化的,
上述公式里其實有些ClampToByte函式是可以不需要的,
上傳下我用于測驗兩個小的32位影像了供有興趣的朋友測驗,

圖片非常小啊,注意仔細觀察并下載,
如果想時刻關注本人的最新文章,也可關注公眾號:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/376883.html
標籤:其他
