RGB和Bitmap互相转换
之前做人脸识别的时候遇到一个问题,把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;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
第二种方法:
/**
* @方法描述 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;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
说明
第二种方法应置于子线程中,放在主线程可能造成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;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
说明
这个方法是使用java实现的,如果需要更高效的速度,可以使用本地方法实现。
好,先这样,有问题随时交流。