赞
踩
前言:本片记录下纯Java下打开摄像头预览,介绍下Camera1的使用方法。
工程:andriod 4,Camera1
安卓调用摄像头有两种方案,一种是调用intent方法使用摄像头(直接调用系统),另一种是通过camera类使用摄像头(自己写),笔者这里使用第二种方案。
本来想把camera1和camera2的使用都放在一篇文章中写,后来发现审核不过,所以就分两篇介绍了。
一、新建工程
二、权限设置
AndroidManifest.xml设置CAMERA权限,不设置权限的话,会闪退或者报错,这里是安卓4.0,不需要去动态权限申请,5.0后需要。
三、界面设置
.xml中添加
有个红线,下面文章中说了原因,不用管暂时This view is not constrained. It only has designtime positions, so it will jump to (0,0) ..._哒哒呵的博客-CSDN博客
四、Camera1
4.1 Camera类的相关方法
Camera.open(); 打开设备摄像头,并返回一个Camera对象。可以通过返回的对象管理摄像头。
Camera.setPreviewDisplay(SurfaceHolder holder); 设置显示摄像头内容的surfaceView,参数为显示surfaceVIew所对应的surfaceHolder。
Camera.startPreview(); 开始预览摄像头。即在surfaceView上显示摄像头拍摄信息。
Camera.stopPreview(); 关闭摄像头。
Camera.release(); 放开摄像头。
4.2 SurfaceView类的相关方法
SurfaceView.getHolder(); 获得surfaceHolder对象,surfaceHolder能够对surfaceView进行控制,且能够添加回调函数来监控surfaceView的变化,同时我们也需要获得surfaceHolder来作为Camera.setPreviewDisplay();方法的参数。
public abstract void addCallback (SurfaceHolder.Callback callback) ; 为surfaceHolder添加回调方法,我们可以直接在使用方法的时候new 一个callback或者实现callback的接口SurfaceHolder.Callback;
public abstract void setType (int type); 在早期的安卓中,我们需要这个方法来设置surfaceView的类型,一般值设置为SURFACE_TYPE_PUSH_BUFFERS; 但是在API 11中该方法已经过时,系统会默认为其设置值。这点还需要再实际开发中再进行验证。
SurfaceHolder的三个回调函数
- public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) ;
- public void surfaceCreated(SurfaceHolder arg0) ;
- public void surfaceDestroyed(SurfaceHolder arg0);
4.3 使用
- private SurfaceView surfaceview;
- private SurfaceHolder holder;
- private Camera mCamera;
- private Camera.Size size;
- private int facingBack = Camera.CameraInfo.CAMERA_FACING_BACK;
-
- private Camera.CameraInfo mFrontCameraInfo = null;
- private Camera.CameraInfo mBackCameraInfo = null;
- private int mFrontCameraId = -1;
- private int mBackCameraId = -1;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- surfaceview=findViewById(R.id.surfaceView);
- holder= surfaceview.getHolder();
- holder.addCallback(new SurfaceHolder.Callback() {
- @Override
- public void surfaceCreated(SurfaceHolder surfaceHolder) {
- int numberOfCameras = Camera.getNumberOfCameras();
- for (int cameraId = 0; cameraId < numberOfCameras ; cameraId++){
- Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
- Camera.getCameraInfo(cameraId, cameraInfo);
- if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
- // 后置摄像头信息
- mBackCameraId = cameraId;
- mBackCameraInfo = cameraInfo;
- } else if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT){
- // 前置摄像头信息
- mFrontCameraId = cameraId;
- mFrontCameraInfo = cameraInfo;
- }
- }
-
- if(mCamera==null){
- //mCamera.setDisplayOrientation(90);
- mCamera=Camera.open();
- }
-
- try {
- //setCameraParameters();设置camera参数
- //默认情况下camera在surfaceview中的方向与正常方向差了90度,
- // 所以需要使用Camera.setDisplayOrientation(90);来调整。
- //还必须在这里设置,其他地方会闪退,
- mCamera.setDisplayOrientation(90);
-
- mCamera.setPreviewDisplay(holder);
- mCamera.startPreview();//开始预览
- } catch (IOException e){
- e.printStackTrace();
- Toast.makeText(MainActivity.this, "打开相机失败", Toast.LENGTH_SHORT).show();
- }
- }
-
- @Override
- public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
-
- }
-
- @Override
- public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
-
- }
- });
- }
上面代码中将下面设置camera代码注释掉了,只是在开启预览前调整了下显示方向,如果调用这个函数,就不用调显示方向了,因为这里面都设置好了。
-
- private void setCameraParameters() {
- if (mCamera == null) {
- return;
- }
-
- Camera.Parameters parameters = mCamera.getParameters();
- mCamera.setDisplayOrientation(90);//220214 komla 摄像机的预览角度
- //增加对聚焦模式的判断,没有它会很模糊
- List<String> focusModesList = parameters.getSupportedFocusModes();
- if (focusModesList.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
- parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
- } else if (focusModesList.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
- parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
- }
- parameters.setRecordingHint(true);
-
- mCamera.setParameters(parameters);
- mCamera.getParameters().getSupportedVideoSizes();
-
- if (size == null) {
- //所有支持的宽高的集合
- List<Camera.Size> mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();
- //从小到大排序
- Collections.sort(mSupportedPreviewSizes, (o1, o2) -> Integer.compare(o1.width, o2.width));
- //因为尺寸太大也不好,容量也就太大,所以只要满足要求就行,要求是宽大于1000或者高大于800的最小的一个
- for (int num = 0; num < mSupportedPreviewSizes.size(); num++) {
- Camera.Size size1 = mSupportedPreviewSizes.get(num);
- if (size1.width >= 1000 && size1.height >= 800) {
- size = size1;
- break;
- }
- }
- }
- parameters.setPreviewSize(640, 480);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。