天天看點

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

兩幅32位帶Alpha通道的圖像,同時存在混合模式和不透明度的設定,最後混合後的顔色計算公式,在網上很難找到正确的,我這裡通過一步一步的測試,整理了不同情況下的混合公式。

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

      我們假定有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%,如下所示:  

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

         得到的混合結果為  B = 97         G = 76          R = 153        A = 168

         注意這些資料的格式都是 Format32bppArgb,而非Format32bppPArgb,即沒有進行預乘的ARGB資料。

         根據這些資料進行推算,得出以下規律,首先是結果色的A值計算公式如下:

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

         其中ClampToByte函數的作用為限制括号内的資料在0和255之間,如果大于255,則取255,如果小于0,則取0值。

         按照此公式複核下上面的結果看下:

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

        結果正确。

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

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

          把資料帶入核算一下:

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

         同理:

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

       公式完全正确。

      上面的計算如果要保證精度,則A值需要用浮點數儲存,這樣可能在某些場合下造成計算瓶頸,如果要全部用整數運算,可利用用Matlab的符号運算在做簡化。

      在matlab中用如下代碼做測試:

       得到結果:

                B1 - (255*A2*(B1 - B2))/(255*A2 - A1*(A2 - 255))

        這個結果隻有一個除法,而且可以看到除法的分子和分母的資料也不會大于int32所能表達的範圍。這樣可借助于整數的除法實作結果。

場景二:僅僅改變圖層混合模式

        我們僅僅改變前景色圖層的混合模式,而不改變其不透明度。以正片疊底模式為例,如下圖所示:       

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

        此時前述兩個顔色的混合值如下所示:

                  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分量的混合公式為:

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

        把資料帶入核算一下:

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

        G和R的值就不進行重複的核算了。

        這個計算式用Maltab去簡化的話基本沒有任何效果。

場景三:僅僅改變圖層的不透明度

         如下所示設定,前景層的不透明度為70%。

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

       此時前述兩個顔色的混合值如下所示:

                       B = 108        G = 80          R = 147        A = 139

       所有的顔色都變了。

       還是先來看A值,經過測試比對,此時A值的計算公式為:

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

        其中O表示不透明度的值,有效範圍是[0,100]。

        核算一下:

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

       對于A值,我們可以認為不透明度首先修改了改成的Alpha,然後再拿這個新的Alpha和底層的Alpha進行正常的混合。

       對于RGB各分量,經過推到和測試結果如下(以B分量為例):

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

       正确無誤。

 場景四:同時改變圖層混合模式和不透明度

        如下所示設定,同時設定混合模式為正片疊底,不透明度為70%。

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

          此時前述兩個顔色的混合值如下所示:

                   B = 103        G = 72          R = 130        A = 139

          可以看到,A值和混合模式沒啥關系,之和不透明度有關,直接用隻改變不透明度時的公式:

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

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

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

        測試下:

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

        完全正确。

        那麼在寫代碼的時候,我們最需要優化的就是這個情況的公式。不過用matlab測試這個公式沒啥好優化的。

       上述公式裡其實有些ClampToByte函數是可以不需要的。

       上傳下我用于測試兩個小的32位圖像了供有興趣的朋友測試。

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

        圖檔非常小啊,注意仔細觀察并下載下傳。

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

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

繼續閱讀