【PS演算法理論探討一】 Photoshop中兩個32點陣圖像混合的計算公式(含不透明度和圖層混合模式)。

Imageshop發表於2021-12-08

      大家可以在網上搜尋相關的主題啊,你可以搜尋到一堆,不過似乎沒有那一個講的很全面,我這裡抽空整理和測試一下資料,分享給大家。

      我們假定有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點陣圖像了供有興趣的朋友測試。

                

        圖片非常小啊,注意仔細觀察並下載。

       如果想時刻關注本人的最新文章,也可關注公眾號:

                                 【PS演算法理論探討一】 Photoshop中兩個32點陣圖像混合的計算公式(含不透明度和圖層混合模式)。

相關文章