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);
    }

如果是多图层混合的话,可以通过递归自底向上地,每次递归完成后把合成后的图片作为底层图,再把新的顶层图放入进一步混合,知道所有图片混合完毕。

猜你喜欢

转载自blog.csdn.net/cjzjolly/article/details/84873026
今日推荐