安卓获取摄像头帧率_Android 关于获取摄像头帧数据

本文介绍了如何在Android中获取摄像头的帧率,并展示了将NV21格式的预览数据转换为Bitmap的实现过程。通过设置Camera.Parameters获取预览帧率,并在onPreviewFrame中处理YUV数据,将其解码为RGB格式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一部分:

由于Android下摄像头预览数据只能 ImageFormat.NV21 格式的,所以解码时要经过一翻周折.

Camera mCamera = Camera.open();

Camera.Parameters p = mCamera.getParameters();

p.setPreviewFormat(ImageFormat.NV21);

mCamera.setParameters(p);

mCamera.startPreview();

下面是解码核心部分:

@Override

publicvoidonPreviewFrame(byte[] data, Camera camera) {

Size size = camera.getParameters().getPreviewSize();

try{

YuvImage image = newYuvImage(data, ImageFormat.NV21, size.width, size.height,null);

if(image!=null){

ByteArrayOutputStream stream = newByteArrayOutputStream();

image.compressToJpeg(newRect(0,0, size.width, size.height),80, stream);

Bitmap bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());

stream.close();

}

}catch(Exception ex){

Log.e("Sys","Error:"+ex.getMessage());

}

}

代码很简单。就是把YUV数据转成 Bitmap 就行了,系统提供

YuvImage 类。

第二部分:

原理是利用手机的摄像头取景,然后解码视频流

拆分成位图,然后对位图进行处理和识别

要在android手机里面捕获视频流

当然,手机必须得有摄像头

然后嘛,第一步是在AndroidManifest.xml加入如下权限声明

<permission android:name="android.permission.CAMERA">permission>

<uses-permission android:name="android.permission.CAMERA" />

<uses-feature android:name="android.hardware.camera" />

<uses-feature android:name="android.hardware.camera.autofocus" />

摄像头的预览和捕获只能通过surfaceview..

而且他的工作模式必须是SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS

不然不能在surfaceview里面显示出预览的图像

然后在surfaceCreated方法里面加入我们的摄像头初始化

public void surfaceCreated(SurfaceHolder arg0) {

//启动相机服务

mCamera = Camera.open();

Log.i("Camera", "surface open");

try {

//设置预览 这个holder是 SurfaceView的getHolder()方法得到的

mCamera.setPreviewDisplay(holder);

Camera.Parameters parameters = mCamera.getParameters();

//设置图片格式

parameters.setPictureFormat(PixelFormat.JPEG);

//设置预览的帧数,受硬件影响.

parameters.setPreviewFrameRate(10);

//设置尺寸

parameters.setPreviewSize(preV.getWidth(), preV.getHeight());

mCamera.setParameters(parameters);

//设置回调的类

mCamera.setPreviewCallback(new ViewCallback(preV, this));

//开始预览

mCamera.startPreview();

} catch (Exception e) {

//释放相机

mCamera.release();

mCamera = null;

return;

}

}

然后看看我们的ViewCallback类

在这个类里面要实现PreviewCallback

主要是里面的 public void onPreviewFrame(byte[] data, Camera arg1)

{}

data就是返回的数据流了, 不过麻烦的是这个流并不是rgb编码的,是YUV420SP编码的,

Camera.Parameters

里面有个setPreviewFormat() 这个虽然可以设置

但是具体能不能编码成JPEG是受你的手机影响的

其中的data是yuv格式的,需要对其解码:

static public void decodeYUV420SP(byte[]

rgbBuf, byte[] yuv420sp, int width, int height) {

final int

frameSize = width * height;

if (rgbBuf

== null)

throw new

NullPointerException("buffer 'rgbBuf' is null");

if

(rgbBuf.length < frameSize * 3)

throw new

IllegalArgumentException("buffer 'rgbBuf' size "

+ rgbBuf.length + " < minimum " + frameSize * 3);

if (yuv420sp

== null)

throw new NullPointerException("buffer

'yuv420sp' is null");

if

(yuv420sp.length < frameSize * 3 / 2)

throw new

IllegalArgumentException("buffer 'yuv420sp' size " +

yuv420sp.length

+ " < minimum " + frameSize * 3 / 2);

int i = 0, y = 0;

int uvp = 0, u = 0, v = 0;

int y1192 = 0, r = 0, g = 0, b = 0;

for (int j = 0, yp = 0; j < height; j++) {

uvp = frameSize + (j >> 1) * width;

u = 0;

v = 0;

for (i = 0; i < width; i++, yp++) {

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;

}

y1192 = 1192 * y;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值