Android图像处理

OpenCV for Android (2)——反色

2018-02-23  本文已影响6人  洋芋掉到碗里去了

反色又叫补色,红的补色是绿色,蓝的补色是橙色,黄的补色是紫色,由这三种对比关系可引出很多对比的反色。

1. 关于ARGB_8888、ALPHA_8、ARGB_4444、RGB_565的理解

1.1 相关信息

A:透明度
R:红色
G:绿
B:蓝

1.2 区别

这四种类型为bitmap在内存中存在的四种色彩的存储模式,他们本质区别体现在每种模式下的bitmap内部的每个像素点,在内存中的大小和组成成分的区别。

名称 定义
Bitmap.Config ARGB_4444 每个像素占四位,即A=4,R=4,G=4,B=4,那么一个像素点占4+4+4+4=16位=2byte
Bitmap.Config ARGB_8888 每个像素占四位,即A=8,R=8,G=8,B=8,那么一个像素点占8+8+8+8=32位=8byte
Bitmap.Config RGB_565 每个像素占四位,即R=5,G=6,B=5,没有透明度,那么一个像素点占5+6+5=16位=2byte
Bitmap.Config ALPHA_8 每个像素占四位,只有透明度,没有颜色,那么一个像素总共占一个字节,8=8bit=1byte

此处设置图片为:
options.inPreferredConfig = Bitmap.Config.ARGB_8888;

2. Mat下的反色操作

其原理是遍历所有的像素点,转换对应像素点并放回。

bgra[sIndex] = (byte) (255 - bgra[sIndex] & 0xff);

public static Bitmap invertMat(Bitmap bitmap) {

        org.opencv.android.Utils.bitmapToMat(bitmap, sSrc);

        //pixel operation
        //宽
        sWidth = sSrc.cols();
        //高
        sHeight = sSrc.rows();
        int cnum = sSrc.channels();//获取通道

        byte[] bgra = new byte[cnum];//ARGB(Bitmap)-->BGRA(mat)

        for (sRow = 0; sRow < sHeight; sRow++) {
            for (sCol = 0; sCol < sWidth; sCol++) {
                sSrc.get(sRow, sCol, bgra);
                for (sIndex = 0; sIndex < cnum; sIndex++) {
                    bgra[sIndex] = (byte) (255 - bgra[sIndex] & 0xff);
                }
                sSrc.put(sRow, sCol, bgra);
            }
        }
        org.opencv.android.Utils.matToBitmap(sSrc, bitmap);
        sSrc.release();

        return bitmap;
    }

这个方法原理简单,但是由于三层for循环,其操作效率低下,需要等待很长时间才能将图片反色显示出来。

3. Bitmap下的反色操作

public static Bitmap invertBitmap(Bitmap bitmap) {
        sWidth = bitmap.getWidth();
        sHeight = bitmap.getHeight();
        sPixels = new int[sWidth * sHeight];
        bitmap.getPixels(sPixels, 0, sWidth, 0, 0, sWidth, sHeight);

        sIndex = 0;
        for (sRow = 0; sRow < sHeight; sRow++) {
            sIndex = sRow * sWidth;
            for (sCol = 0; sCol < sWidth; sCol++) {
                sPixel = sPixels[sIndex];
                sA = (sPixel >> 24) & 0xff;
                sR = (sPixel >> 16) & 0xff;
                sG = (sPixel >> 8) & 0xff;
                sB = sPixel & 0xff;

                sR = 255 - sR;
                sG = 255 - sG;
                sB = 255 - sB;

                sPixel = ((sA & 0xff) << 24 | (sR & 0xff) << 16 | (sG & 0xff) << 8 | sB & 0xff);

                sPixels[sIndex] = sPixel;

                sIndex++;
            }
        }
        bitmap.setPixels(sPixels, 0, sWidth, 0, 0, sWidth, sHeight);
        return bitmap;
    }

相对使用Mat的操作,Bitmap转换的速度将会相对快一些,但遇到大图片时依旧不够快。


Demo: learnOpenCV

上一篇 下一篇

猜你喜欢

热点阅读