//=================== YV12ToRGB24=======方法1
public static class YV12ToRGB24 {
private static final int[] Table_fv1 = { -180, -179, -177, -176, -174,
-173, -172, -170, -169, -167, -166, -165, -163, -162, -160, -159,
-158, -156, -155, -153, -152, -151, -149, -148, -146, -145, -144,
-142, -141, -139, -138, -137, -135, -134, -132, -131, -130, -128,
-127, -125, -124, -123, -121, -120, -118, -117, -115, -114, -113,
-111, -110, -108, -107, -106, -104, -103, -101, -100, -99, -97,
-96, -94, -93, -92, -90, -89, -87, -86, -85, -83, -82, -80, -79,
-78, -76, -75, -73, -72, -71, -69, -68, -66, -65, -64, -62, -61,
-59, -58, -57, -55, -54, -52, -51, -50, -48, -47, -45, -44, -43,
-41, -40, -38, -37, -36, -34, -33, -31, -30, -29, -27, -26, -24,
-23, -22, -20, -19, -17, -16, -15, -13, -12, -10, -9, -8, -6, -5,
-3, -2, 0, 1, 2, 4, 5, 7, 8, 9, 11, 12, 14, 15, 16, 18, 19, 21, 22,
23, 25, 26, 28, 29, 30, 32, 33, 35, 36, 37, 39, 40, 42, 43, 44, 46,
47, 49, 50, 51, 53, 54, 56, 57, 58, 60, 61, 63, 64, 65, 67, 68, 70,
71, 72, 74, 75, 77, 78, 79, 81, 82, 84, 85, 86, 88, 89, 91, 92, 93,
95, 96, 98, 99, 100, 102, 103, 105, 106, 107, 109, 110, 112, 113,
114, 116, 117, 119, 120, 122, 123, 124, 126, 127, 129, 130, 131,
133, 134, 136, 137, 138, 140, 141, 143, 144, 145, 147, 148, 150,
151, 152, 154, 155, 157, 158, 159, 161, 162, 164, 165, 166, 168,
169, 171, 172, 173, 175, 176, 178 };
private static final int[] Table_fv2 = { -92, -91, -91, -90, -89, -88, -88,
-87, -86, -86, -85, -84, -83, -83, -82, -81, -81, -80, -79, -78,
-78, -77, -76, -76, -75, -74, -73, -73, -72, -71, -71, -70, -69,
-68, -68, -67, -66, -66, -65, -64, -63, -63, -62, -61, -61, -60,
-59, -58, -58, -57, -56, -56, -55, -54, -53, -53, -52, -51, -51,
-50, -49, -48, -48, -47, -46, -46, -45, -44, -43, -43, -42, -41,
-41, -40, -39, -38, -38, -37, -36, -36, -35, -34, -33, -33, -32,
-31, -31, -30, -29, -28, -28, -27, -26, -26, -25, -24, -23, -23,
-22, -21, -21, -20, -19, -18, -18, -17, -16, -16, -15, -14, -13,
-13, -12, -11, -11, -10, -9, -8, -8, -7, -6, -6, -5, -4, -3, -3,
-2, -1, 0, 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 7, 8, 9, 10, 10, 11, 12,
12, 13, 14, 15, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 24,
25, 25, 26, 27, 27, 28, 29, 30, 30, 31, 32, 32, 33, 34, 35, 35, 36,
37, 37, 38, 39, 40, 40, 41, 42, 42, 43, 44, 45, 45, 46, 47, 47, 48,
49, 50, 50, 51, 52, 52, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, 60,
61, 62, 62, 63, 64, 65, 65, 66, 67, 67, 68, 69, 70, 70, 71, 72, 72,
73, 74, 75, 75, 76, 77, 77, 78, 79, 80, 80, 81, 82, 82, 83, 84, 85,
85, 86, 87, 87, 88, 89, 90, 90 };
private static final int[] Table_fu1 = { -44, -44, -44, -43, -43, -43, -42,
-42, -42, -41, -41, -41, -40, -40, -40, -39, -39, -39, -38, -38,
-38, -37, -37, -37, -36, -36, -36, -35, -35, -35, -34, -34, -33,
-33, -33, -32, -32, -32, -31, -31, -31, -30, -30, -30, -29, -29,
-29, -28, -28, -28, -27, -27, -27, -26, -26, -26, -25, -25, -25,
-24, -24, -24, -23, -23, -22, -22, -22, -21, -21, -21, -20, -20,
-20, -19, -19, -19, -18, -18, -18, -17, -17, -17, -16, -16, -16,
-15, -15, -15, -14, -14, -14, -13, -13, -13, -12, -12, -11, -11,
-11, -10, -10, -10, -9, -9, -9, -8, -8, -8, -7, -7, -7, -6, -6, -6,
-5, -5, -5, -4, -4, -4, -3, -3, -3, -2, -2, -2, -1, -1, 0, 0, 0, 1,
1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8,
8, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14,
15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20,
20, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26,
26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32,
32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38,
38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 43, 43 };
private static final int[] Table_fu2 = { -227, -226, -224, -222, -220,
-219, -217, -215, -213, -212, -210, -208, -206, -204, -203, -201,
-199, -197, -196, -194, -192, -190, -188, -187, -185, -183, -181,
-180, -178, -176, -174, -173, -171, -169, -167, -165, -164, -162,
-160, -158, -157, -155, -153, -151, -149, -148, -146, -144, -142,
-141, -139, -137, -135, -134, -132, -130, -128, -126, -125, -123,
-121, -119, -118, -116, -114, -112, -110, -109, -107, -105, -103,
-102, -100, -98, -96, -94, -93, -91, -89, -87, -86, -84, -82, -80,
-79, -77, -75, -73, -71, -70, -68, -66, -64, -63, -61, -59, -57,
-55, -54, -52, -50, -48, -47, -45, -43, -41, -40, -38, -36, -34,
-32, -31, -29, -27, -25, -24, -22, -20, -18, -16, -15, -13, -11,
-9, -8, -6, -4, -2, 0, 1, 3, 5, 7, 8, 10, 12, 14, 15, 17, 19, 21,
23, 24, 26, 28, 30, 31, 33, 35, 37, 39, 40, 42, 44, 46, 47, 49, 51,
53, 54, 56, 58, 60, 62, 63, 65, 67, 69, 70, 72, 74, 76, 78, 79, 81,
83, 85, 86, 88, 90, 92, 93, 95, 97, 99, 101, 102, 104, 106, 108,
109, 111, 113, 115, 117, 118, 120, 122, 124, 125, 127, 129, 131,
133, 134, 136, 138, 140, 141, 143, 145, 147, 148, 150, 152, 154,
156, 157, 159, 161, 163, 164, 166, 168, 170, 172, 173, 175, 177,
179, 180, 182, 184, 186, 187, 189, 191, 193, 195, 196, 198, 200,
202, 203, 205, 207, 209, 211, 212, 214, 216, 218, 219, 221, 223,
225 };
private int WIDTH;
private int HEIGHT;
private int PIXELSIZE;
public YV12ToRGB24(int width, int height) {
WIDTH = width;
HEIGHT = height;
PIXELSIZE = width * height;
}
@SuppressWarnings("unused")
public boolean convert(byte[] pYV12, byte[] pRGB24) {
// -----------------------------------------------------
if (pYV12.length == 0 || pRGB24.length == 0)
return false;
final int nYLen = PIXELSIZE;
final int nHfWidth = (WIDTH >> 1);
if (nYLen < 1 || nHfWidth < 1)
return false;
// Y data
// unsigned char* yData = pYV12;
byte[] yData = new byte[pYV12.length];
for (int i = 0; i < pYV12.length; i++)
yData[i] = pYV12[i];
// v data
// unsigned char* vData = &yData[nYLen];
// -----------------------------------------------
byte[] vData = new byte[yData.length - nYLen];
for (int i = 0; i < vData.length; i++)
vData[i] = yData[nYLen + i];
// u data
// unsigned char* uData = &vData[nYLen>>2];
// -------------------------------------------------
byte[] uData = new byte[vData.length - (nYLen >> 2)];
for (int i = 0; i < uData.length; i++) {
// System.out.println(i);
// System.out.println((nYLen>>2) + i);
uData[i] = vData[(nYLen >> 2) + i];
}
if (uData.length == 0 || vData.length == 0)
return false;
// ---------------------------------------------
// int rgb[3];
int[] rgb = new int[3];
int i, j, m, n, x, y, pu, pv, py, rdif, invgdif, bdif;
m = -WIDTH;
n = -nHfWidth;
// --------------------------------------
boolean addhalf = true;
for (y = 0; y < HEIGHT; y++) {
m += WIDTH;
if (addhalf) {
n += nHfWidth;
addhalf = false;
} else {
addhalf = true;
}
for (x = 0; x < WIDTH; x++) {
i = m + x;
j = n + (x >> 1);
py = (int) ((yData[i] + 256) % 256);
// search tables to get rdif invgdif and bidif
rdif = Table_fv1[(int) ((vData[j] + 256) % 256)]; // fv1
invgdif = Table_fu1[(int) ((uData[j] + 256) % 256)]
+ Table_fv2[(int) ((vData[j] + 256) % 256)]; // fu1+fv2
bdif = Table_fu2[(int) ((uData[j] + 256) % 256)]; // fu2
rgb[2] = py + rdif; // R
rgb[1] = py - invgdif; // G
rgb[0] = py + bdif; // B
j = nYLen - WIDTH - m + x;
i = (j << 1) + j;
// copy this pixel to rgb data
for (j = 0; j < 3; j++) {
if (rgb[j] >= 0 && rgb[j] <= 255) {
pRGB24[i + j] = (byte) (rgb[j]);
} else {
pRGB24[i + j] = (byte) ((rgb[j] < 0) ? 0 : 255);
}
}
}
}
return true;
}
}
//==========================YV12ToRGB==============方法2
private static int R = 0;
private static int G = 1;
private static int B = 2;
private static class RGB{
public int r, g, b;
}
private static RGB yuvTorgb(byte Y, byte U, byte V){
RGB rgb = new RGB();
rgb.r = (int)((Y&0xff) + 1.732446 * ((U&0xff)-128));
rgb.g = (int)((Y&0xff) - 0.698001 * ((U&0xff)-128) - 0.703125*((V&0xff)-128));
rgb.b = (int)((Y&0xff) + 1.370705 * ((V&0xff)-128));
rgb.r =(rgb.r<0? 0: rgb.r>255? 255 : rgb.r);
rgb.g =(rgb.g<0? 0: rgb.g>255? 255 : rgb.g);
rgb.b =(rgb.b<0? 0: rgb.b>255? 255 : rgb.b);
return rgb;
}
//YV12是yuv420格式,是3个plane,排列方式为(Y)(V)(U)
public static int[] YV12ToRGB(byte[] src, int width, int height){
int numOfPixel = width * height;
int positionOfV = numOfPixel;
int positionOfU = numOfPixel/4 + numOfPixel;
int[] rgb = new int[numOfPixel*3];
for(int i=0; i<height; i++){
int startY = i*width;
int step = (i/2)*(width/2);
int startV = positionOfV + step;
int startU = positionOfU + step;
for(int j = 0; j < width; j++){
int Y = startY + j;
int V = startV + j/2;
int U = startU + j/2;
int index = Y*3;
//rgb[index+R] = (int)((src[Y]&0xff) + 1.4075 * ((src[V]&0xff)-128));
//rgb[index+G] = (int)((src[Y]&0xff) - 0.3455 * ((src[U]&0xff)-128) - 0.7169*((src[V]&0xff)-128));
//rgb[index+B] = (int)((src[Y]&0xff) + 1.779 * ((src[U]&0xff)-128));
RGB tmp = yuvTorgb(src[Y], src[U], src[V]);
rgb[index+R] = tmp.r;
rgb[index+G] = tmp.g;
rgb[index+B] = tmp.b;
}
}
return rgb;
}
//=========================createMyBitmap====rgbTo24Bitmap=============方法1
/*
* byte[] data保存的是纯RGB的数据,而非完整的图片文件数据
*/
static public Bitmap createMyBitmap(byte[] data, int width, int height){
int []colors = convertByteToColor(data);
if (colors == null){
return null;
}
Bitmap bmp = null;
try {
bmp = Bitmap.createBitmap(colors, 0, width, width, height,
Bitmap.Config.ARGB_8888);
} catch (Exception e) {
// TODO: handle exception
return null;
}
return bmp;
}
/*
* 将RGB数组转化为像素数组
*/
private static int[] convertByteToColor(byte[] data){
int size = data.length;
if (size == 0){
return null;
}
// 理论上data的长度应该是3的倍数,这里做个兼容
int arg = 0;
if (size % 3 != 0){
arg = 1;
}
int []color = new int[size / 3 + arg];
int red, green, blue;
if (arg == 0){ // 正好是3的倍数
for(int i = 0; i < color.length; ++i){
color[i] = (data[i * 3] << 16 & 0x00FF0000) |
(data[i * 3 + 1] << 8 & 0x0000FF00 ) |
(data[i * 3 + 2] & 0x000000FF ) |
0xFF000000;
}
}else{ // 不是3的倍数
for(int i = 0; i < color.length - 1; ++i){
color[i] = (data[i * 3] << 16 & 0x00FF0000) |
(data[i * 3 + 1] << 8 & 0x0000FF00 ) |
(data[i * 3 + 2] & 0x000000FF ) |
0xFF000000;
}
color[color.length - 1] = 0xFF000000; // 最后一个像素用黑色填充
}
return color;
}
//===================rgbToBitmap========================方法2
public static Bitmap rgbToBitmap(int[] rgb, int width, int height) {
if (rgb == null)
throw new NullPointerException();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
bitmap.setPixels(rgb, 0, width, 0, 0, width, height);
return bitmap;
}
//====================== rgbToBitmap=====================方法3
private static Bitmap mSmallRstBmp = null;
public static Bitmap rgbToBitmap2(byte[] rgb, int width, int height){
if(mSmallRstBmp == null)
{
mSmallRstBmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
}
byte[] rawDataTmp = new byte [rgb.length];
System.arraycopy(rgb, 0, rawDataTmp, 0, rgb.length);
ByteBuffer localByteBuffer = ByteBuffer.wrap(rawDataTmp);
// localByteBuffer.rewind();//
mSmallRstBmp.copyPixelsFromBuffer(localByteBuffer);
// localByteBuffer.position(0);//将buffer的下一读写位置置为0。//
// mSmallRstBmp.recycle();//
return mSmallRstBmp;
}
Android相机,YV12ToRGB24,rgbToBitmap
最新推荐文章于 2024-07-15 09:56:35 发布