RGB和Bitmap互相转换

来源:互联网 发布:淘宝刀具 编辑:程序博客网 时间:2024/05/22 02:38

之前做人脸识别的时候遇到一个问题,把RGB数据转换成Bitmap。所以决定写一个RGB和Bitmap互相转换的工具类分享给大家。

1、Bitmap转RGB
获取Bitmap的RGB数组一共有两个方法,接下来简答说明下

第一种方法:

 /**     * @方法描述 Bitmap转RGB     */    public static byte[] bitmap2RGB(Bitmap bitmap) {        int bytes = bitmap.getByteCount();  //返回可用于储存此位图像素的最小字节数        ByteBuffer buffer = ByteBuffer.allocate(bytes); //  使用allocate()静态方法创建字节缓冲区        bitmap.copyPixelsToBuffer(buffer); // 将位图的像素复制到指定的缓冲区        byte[] rgba = buffer.array();        byte[] pixels = new byte[(rgba.length / 4) * 3];        int count = rgba.length / 4;        //Bitmap像素点的色彩通道排列顺序是RGBA        for (int i = 0; i < count; i++) {            pixels[i * 3] = rgba[i * 4];        //R            pixels[i * 3 + 1] = rgba[i * 4 + 1];    //G            pixels[i * 3 + 2] = rgba[i * 4 + 2];       //B        }        return pixels;    }

第二种方法:

    /**     * @方法描述 Bitmap转RGB     */    public static byte[] getRGBFromBMP(Bitmap bmp) {        int w = bmp.getWidth();        int h = bmp.getHeight();        byte[] pixels = new byte[w * h * 3]; // Allocate for RGB        int k = 0;        for (int x = 0; x < h; x++) {            for (int y = 0; y < w; y++) {                int color = bmp.getPixel(y, x);                pixels[k * 3] = (byte) Color.red(color);                pixels[k * 3 + 1] = (byte) Color.green(color);                pixels[k * 3 + 2] = (byte) Color.blue(color);                k++;            }        }        return pixels;    }

说明
第二种方法应置于子线程中,放在主线程可能造成ANR。建议使用第一种方法,其内部使用了本地方法复制像素值,效率更高更安全。

2、RGB转Bitmap
这个方法是很久之前从网上找到的,具体是哪位兄弟写的已经无从查证,在这里先谢谢这位乐于分享的程序猿兄弟。
* 该方法亲测可用。欢迎大家使用。

/**     * @方法描述 将RGB字节数组转换成Bitmap,     */    static public Bitmap rgb2Bitmap(byte[] data, int width, int height) {        int[] colors = convertByteToColor(data);    //取RGB值转换为int数组        if (colors == null) {            return null;        }        Bitmap bmp = Bitmap.createBitmap(colors, 0, width, width, height,                Bitmap.Config.ARGB_8888);        return bmp;    }    // 将一个byte数转成int    // 实现这个函数的目的是为了将byte数当成无符号的变量去转化成int    public static int convertByteToInt(byte data) {        int heightBit = (int) ((data >> 4) & 0x0F);        int lowBit = (int) (0x0F & data);        return heightBit * 16 + lowBit;    }    // 将纯RGB数据数组转化成int像素数组    public static int[] convertByteToColor(byte[] data) {        int size = data.length;        if (size == 0) {            return null;        }        int arg = 0;        if (size % 3 != 0) {            arg = 1;        }        // 一般RGB字节数组的长度应该是3的倍数,        // 不排除有特殊情况,多余的RGB数据用黑色0XFF000000填充        int[] color = new int[size / 3 + arg];        int red, green, blue;        int colorLen = color.length;        if (arg == 0) {            for (int i = 0; i < colorLen; ++i) {                red = convertByteToInt(data[i * 3]);                green = convertByteToInt(data[i * 3 + 1]);                blue = convertByteToInt(data[i * 3 + 2]);                // 获取RGB分量值通过按位或生成int的像素值                color[i] = (red << 16) | (green << 8) | blue | 0xFF000000;            }        } else {            for (int i = 0; i < colorLen - 1; ++i) {                red = convertByteToInt(data[i * 3]);                green = convertByteToInt(data[i * 3 + 1]);                blue = convertByteToInt(data[i * 3 + 2]);                color[i] = (red << 16) | (green << 8) | blue | 0xFF000000;            }            color[colorLen - 1] = 0xFF000000;        }        return color;    }

说明
这个方法是使用java实现的,如果需要更高效的速度,可以使用本地方法实现。
好,先这样,有问题随时交流。

1 0
原创粉丝点击