1. 程式人生 > >Android圖片顏色混合演算法

Android圖片顏色混合演算法

最近寫的工程其中有一步是是把兩張圖片根據透明度混合起來生成一張新的圖片,我也完成了這個功能。原來其實比較簡單,把兩張圖片分為頂部圖片和頂部圖片,取頂部圖片每畫素的透明度為k,那麼底部每畫素的透明度則需要設定為(1-k)使得加起來百分比為1。然後分割畫素為紅綠藍通道,然後分別乘以對應對應的透明度再加起來成為新的紅綠藍通道,然後把紅綠藍值通過移位運算合成新畫素即可。

程式碼如下(預設畫素編碼為ARGB8888格式,其他格式需要修改移位運算部分):

    public static Bitmap combineBitmap(Bitmap bottomLayer, Bitmap topLayer){
        if(bottomLayer.getHeight() != topLayer.getHeight() || bottomLayer.getWidth() != topLayer.getWidth()){
            return null;
        }
        int canvasDataBottom[] = new int[bottomLayer.getWidth() * bottomLayer.getHeight()];
        int canvasDataTop[] = new int[topLayer.getWidth() * topLayer.getHeight()];
        bottomLayer.copyPixelsToBuffer(IntBuffer.wrap(canvasDataBottom));
        topLayer.copyPixelsToBuffer(IntBuffer.wrap(canvasDataTop));
        //canvasData2和canvasData依據兩者透明度混合
        int canvasDataCombine[] = new int[canvasDataBottom.length];
        for(int i = 0; i < canvasDataBottom.length; i++){
            float k = (float) (canvasDataTop[i] >> 24 & 0xFF) / 255f; //取頂部畫素第一位元組作為透明度,除以0xFF求該頂部畫素有多不透明
            float reverseK = 1f - k;  //底部畫素有多不透明(底部不透明度+頂部不透明度為1,剛好為完全不透明)
            //紅綠藍元素分別做同一操作:頂部畫素淡化為只有(k * 100)%的程度,加上淡化為((1-k)* 100)%程度的底部畫素形成混合畫素。當頂部k為1時,頂部完全不透明;(1-k)為0,底部完全透明,反之亦然。
            int r = (int)((canvasDataTop[i] >> 16 & 0xFF) * k + (canvasDataBottom[i] >> 16 & 0xFF) * reverseK);
            int g = (int)((canvasDataTop[i] >> 8 & 0xFF) * k + (canvasDataBottom[i] >> 8 & 0xFF) * reverseK);
            int b = (int)((canvasDataTop[i] & 0xFF) * k + (canvasDataBottom[i] & 0xFF) * reverseK);
            canvasDataCombine[i] |= 0xFF000000;
            canvasDataCombine[i] |= (r << 16);
            canvasDataCombine[i] |= (g << 8);
            canvasDataCombine[i] |= b;
        }
        return  Bitmap.createBitmap(canvasDataCombine, bottomLayer.getWidth(), bottomLayer.getHeight(), Bitmap.Config.ARGB_8888);
    }

如果是多圖層混合的話,可以通過遞迴自底向上地,每次遞迴完成後把合成後的圖片作為底層圖,再把新的頂層圖放入進一步混合,知道所有圖片混合完畢。