Android Camera设置setPreviewCallback实现onPreviewFrame接口实时截取每一帧视频流数据

1 概述

通过Android Camera拍摄预览中设置setPreviewCallback实现onPreviewFrame接口,实时截取每一帧视频流数据


2 知识点

① Android Camera使用:    参考 Refs/Related 0-4

Camera 支持格式

拍照流程


② Android SurfaceView使用:  参考 Refs/Related 5-10

③ Camera权限


3 核心源码

① SurfaceView相关 

// 定义对象
private SurfaceView mSurfaceview = null; // SurfaceView对象:(视图组件)视频显示
private SurfaceHolder mSurfaceHolder = null; // SurfaceHolder对象:(抽象接口)SurfaceView支持类
private Camera mCamera =null; // Camera对象,相机预览
复制代码
 // InitSurfaceView
private void initSurfaceView()
{
mSurfaceview = (SurfaceView) this.findViewById(R.id.Surfaceview);
mSurfaceHolder = mSurfaceview.getHolder(); // 绑定SurfaceView,取得SurfaceHolder对象
mSurfaceHolder.addCallback(mainActivity.this); // SurfaceHolder加入回调接口
// mSurfaceHolder.setFixedSize(176, 144); // 预览大小設置
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);// 設置顯示器類型,setType必须设置
}
复制代码

② 主Activity实现SurfaceHolder.Callback接口,编写回调函数

复制代码
/*【SurfaceHolder.Callback 回调函数】*/
public void surfaceCreated(SurfaceHolder holder)
// SurfaceView启动时/初次实例化,预览界面被创建时,该方法被调用。
{
// TODO Auto-generated method stub
mCamera = Camera.open();// 开启摄像头(2.3版本后支持多摄像头,需传入参数)
try
{
Log.i(TAG, "SurfaceHolder.Callback:surface Created");
mCamera.setPreviewDisplay(mSurfaceHolder);//set the surface to be used for live preview

} catch (Exception ex)
{
if(null != mCamera)
{
mCamera.release();
mCamera = null;
}
Log.i(TAG+"initCamera", ex.getMessage());
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
// 当SurfaceView/预览界面的格式和大小发生改变时,该方法被调用
{
// TODO Auto-generated method stub
Log.i(TAG, "SurfaceHolder.Callback:Surface Changed");
//mPreviewHeight = height;
//mPreviewWidth = width;
initCamera();
}
public void surfaceDestroyed(SurfaceHolder holder)
// SurfaceView销毁时,该方法被调用
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Camera.setPreviewCallback 用于设置预览的回调函数,可以在该函数中处理摄像头采集到的每一帧数据。如果你想旋转视频流,可以在回调函数中进行相应操作。以下是一个示例代码,演示如何通过设置预览回调函数来旋转视频流: ```java public class MainActivity extends AppCompatActivity implements Camera.PreviewCallback { private Camera mCamera; private SurfaceView mSurfaceView; private SurfaceHolder mSurfaceHolder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mSurfaceView = findViewById(R.id.surfaceView); mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.addCallback(this); } @Override public void surfaceCreated(SurfaceHolder holder) { mCamera = Camera.open(); mCamera.setDisplayOrientation(90); // 设置预览显示方向为竖屏,默认是横屏 try { mCamera.setPreviewDisplay(holder); mCamera.setPreviewCallback(this); mCamera.startPreview(); } catch (IOException e) { e.printStackTrace(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // 横竖屏切换时,需要重新设置预览显示方向 if (mCamera != null) { if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { mCamera.setDisplayOrientation(90); } else { mCamera.setDisplayOrientation(0); } mCamera.startPreview(); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { mCamera.setPreviewCallback(null); mCamera.stopPreview(); mCamera.release(); mCamera = null; } @Override public void onPreviewFrame(byte[] data, Camera camera) { // 在这里可以对视频流进行操作,例如旋转、处理每一帧数据等 // 这里只是简单地将视频流旋转90度 byte[] rotatedData = new byte[data.length]; for (int i = 0; i < mPreviewSize.width; i++) { for (int j = 0; j < mPreviewSize.height; j++) { rotatedData[i * mPreviewSize.height + j] = data[j * mPreviewSize.width + mPreviewSize.width - i - 1]; } } // 处理完视频流后,可以将数据传给其他模块进行进一步处理或显示 } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值