Android上Camera获取byte数据在native层进行转换
jbyte * pBuf = (jbyte*)env->GetByteArrayElements(yuv, 0);
int width = w;
int height = h + h / 2;
Mat imageSrc(height, width , CV_8UC1, (unsigned char*)pBuf );
Mat image;
cvtColor(imageSrc, image, CV_YUV2BGR_NV21);
Mat timage;
transpose(image, timage);
Mat ximage;
Mat yimage;
flip(timage, ximage, 0);
flip(ximage, yimage, 1);
Android的Bitmap图像格式转为BGRA
public void onPreviewFrame(byte[] data, Camera camera) {
if (data != null) {
int imageWidth = mCamera.getParameters().getPreviewSize().width;
int imageHeight = mCamera.getParameters().getPreviewSize().height;
int RGBData[] = new int[imageWidth * imageHeight];
decodeYUV420SP(RGBData, data, imageWidth, imageHeight);// 解码,yuv420sp转为RGB格式
Bitmap bm = Bitmap.createBitmap(RGBData, imageWidth,imageHeight, Config.ARGB_8888);//填到bitmap中
byte[] bgra = getPixelsBGRA(bm);//把bitmap中的ARGB_8888格式转为Mat矩阵中可用的BGRA格式数据bgra
}
}
public byte[] getPixelsBGRA(Bitmap image) {
// calculate how many bytes our image consists of
int bytes = image.getByteCount();
ByteBuffer buffer = ByteBuffer.allocate(bytes); // Create a new buffer
image.copyPixelsToBuffer(buffer); // Move the byte data to the buffer
byte[] temp = buffer.array(); // Get the underlying array containing the data.
byte[] pixels = new byte[temp.length]; // Allocate for BGRA
// Copy pixels into place
for (int i = 0; i < (temp.length / 4); i++) {
pixels[i * 4] = temp[i * 4 + 2]; //B
pixels[i * 4 + 1] = temp[i * 4 + 1];<span style="white-space:pre"> </span>//G
pixels[i * 4 + 2] = temp[i * 4 ]; //R
pixels[i * 4 + 3] = temp[i * 4 + 3]; //A
}
return pixels;
}
static public void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width,
int height) {
final int frameSize = width * height;
for (int j = 0, yp = 0; j < height; j++) {
int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
for (int i = 0; i < width; i++, yp++) {
int y = (0xff & ((int) yuv420sp[yp])) - 16;
if (y < 0)
y = 0;
if ((i & 1) == 0) {
v = (0xff & yuv420sp[uvp++]) - 128;
u = (0xff & yuv420sp[uvp++]) - 128;
}
int y1192 = 1192 * y;
int r = (y1192 + 1634 * v);
int g = (y1192 - 833 * v - 400 * u);
int b = (y1192 + 2066 * u);
if (r < 0)
r = 0;
else if (r > 262143)
r = 262143;
if (g < 0)
g = 0;
else if (g > 262143)
g = 262143;
if (b < 0)
b = 0;
else if (b > 262143)
b = 262143;
rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000)
| ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
}
}
}
在Canvas上绘图、写字。
public void drawLine(double[] rects) {
Canvas canvas = sh.lockCanvas();
canvas.drawColor(Color.TRANSPARENT);
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawPaint(paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
if (rects == null) {
Log.d("tag", "null");
sh.unlockCanvasAndPost(canvas);
return;
}
if (rects.length == 0) {
Log.d("tag", "null");
sh.unlockCanvasAndPost(canvas);
return;
}
paint.setAntiAlias(true);
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
for (int i = 0; i < rects.length; i += 4) {
int x = (int)((1.0-rects[i])*mWidth);
int y = (int)(rects[i+1]*mHeight*1.5);
int w = (int)((rects[i+2])*mWidth);
int h = (int)((rects[i+3])*mHeight);
canvas.drawRect(x, y, x+w, y+h, paint);
String str = "x:"+x + ",y:" + y;
Paint p = new Paint();
p.setColor(Color.YELLOW);
p.setAntiAlias(true);//去除锯齿
p.setFilterBitmap(true);//对位图进行滤波处理
p.setTextSize(30.0f);
canvas.drawText(str,x,y,p);
}
sh.unlockCanvasAndPost(canvas);
}
YUV旋转
void rotateYUV240SP(byte[] src,byte[] des,int width,int height)
{
int wh = width * height;
//旋转Y
int k = 0;
for(int i=0;i<width;i++) {
for(int j=0;j<height;j++)
{
des[k] = src[width*j + i];
k++;
}
}
for(int i=0;i<width;i+=2) {
for(int j=0;j<height/2;j++)
{
des[k] = src[wh+ width*j + i];
des[k+1]=src[wh + width*j + i+1];
k+=2;
}
}
}