6、纯java调用摄像头预览小记1--Camera1

前言:本片记录下纯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);
    }

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值