camera2实现预览

public class Camera2Helper implements SurfaceHolder.Callback {

    private int mCameraId;
    private final SurfaceView mSurfaceView;
    private ImageReader mImageReader;
    private int mWidth = 0;
    private int mHeight = 0;
    private Handler tCameraHandler;
    private CameraCaptureSession mCameraCaptureSession;
    private HandlerThread tHandlerThread;
    private volatile CameraDevice mCameraDevice;
    public void setWidth(int width) {
        this.mWidth = width;
    }

    public void setHeight(int height) {
        this.mHeight = height;
    }

    public Camera2Helper(int cameraId, SurfaceView surfaceView) {
        mCameraId = cameraId;
        mSurfaceView = surfaceView;
        //保持屏幕长亮
        mSurfaceView.setKeepScreenOn(true);
        mSurfaceView.getHolder().addCallback(this);
    }

    public  void  switchCamera() {
        // 判断是否为空原因,当用户快速点击切换会导致摄像头资源问题,从而系统崩溃
        // 处理思路,切换时只要知道mCameraDevice已经被初始化完成即可,那如何判断呢
        // 每次切换会释放mCameraDevice,每次onOpened完成之后会赋值mCameraDevice
        if(mCameraDevice==null){
            return;
        }
        closeCamera();
        if (CameraCharacteristics.LENS_FACING_BACK == mCameraId) {
            mCameraId = CameraCharacteristics.LENS_FACING_FRONT;
        } else {
            mCameraId = CameraCharacteristics.LENS_FACING_BACK;
        }
        stopThread();
        mSurfaceView.getHolder().addCallback(this);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            initCamera();
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        //home键之后重新初始化
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            initCamera();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        //home键之后surfaceDestroyed这时候不需要摄像头资源则关闭释放
        closeCamera();
        stopThread();
        mSurfaceView.getHolder().addCallback(this);
    }

    public void closeCamera() {
        if (null != mCameraCaptureSession) {
            mCameraCaptureSession.close();
            mCameraCaptureSession = null;
        }
        if (null != mCameraDevice) {
            mCameraDevice.close();
            mCameraDevice = null;
        }
        if (mSurfaceView.getHolder() != null) {
            mSurfaceView.getHolder().removeCallback(this);
        }
    }

    public void stopThread() {
        tHandlerThread.quitSafely();
        try {
            tHandlerThread.join();
            tHandlerThread = null;
            tCameraHandler = null;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @SuppressLint("MissingPermission")
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void initCamera() {
        tHandlerThread = new HandlerThread("Camera2");
        tHandlerThread.start();
        tCameraHandler = new Handler(mSurfaceView.getContext().getMainLooper());
        mImageReader = ImageReader.newInstance(mWidth, mHeight,
                ImageFormat.YUV_420_888, 1);
        mImageReader.setOnImageAvailableListener(new ImageReader
                .OnImageAvailableListener() {
            @Override
            public void onImageAvailable(ImageReader reader) {

            }
        }, tCameraHandler);
        CameraManager mCameraManager = null;
        mCameraManager = (CameraManager) mSurfaceView.getContext().getSystemService(Context.CAMERA_SERVICE);
        try {
            mCameraManager.openCamera(String.valueOf(mCameraId), mStateCallback, tCameraHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * 摄像头创建监听
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(@NonNull CameraDevice camera) { // 打开摄像头
            mCameraDevice = camera;
            // 开启预览
            createPreview();
        }

        @Override
        public void onDisconnected(@NonNull CameraDevice camera) { // 关闭摄像头
            if (null != mCameraDevice) {
                mCameraDevice.close();
                mCameraDevice = null;
            }
        }

        @Override
        public void onError(@NonNull CameraDevice camera, int error) { // 发生错误

        }
    };

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void createPreview() {
        try {
            // 创建预览需要的CaptureRequest.Builder
            final CaptureRequest.Builder previewRequestBuilder = mCameraDevice
                    .createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            // 将SurfaceView的surface作为CaptureRequest.Builder的目标
            previewRequestBuilder.addTarget(mSurfaceView.getHolder().getSurface());
//            previewRequestBuilder.addTarget(mImageReader.getSurface());
            // 创建CameraCaptureSession,该对象负责管理处理预览请求
            mCameraDevice.createCaptureSession(Arrays.asList(mSurfaceView.getHolder().getSurface()),
                    new CCSStateCallback(previewRequestBuilder),
                    tCameraHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    class CCSStateCallback extends CameraCaptureSession.StateCallback {
        private CaptureRequest.Builder previewRequestBuilder;

        CCSStateCallback(CaptureRequest.Builder previewRequestBuilder) {
            this.previewRequestBuilder = previewRequestBuilder;
        }

        @Override
        public void onConfigured(CameraCaptureSession session) {
            if (null == mCameraDevice) {
                return;
            }
            //  当摄像头已经准备好时,开始显示预览
            mCameraCaptureSession = session;
            try {
                //  自动对焦
//                previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
//                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                //  显示预览
                CaptureRequest previewRequest = previewRequestBuilder.build();
                mCameraCaptureSession.setRepeatingRequest(previewRequest,
                        null, tCameraHandler);
            } catch (CameraAccessException | IllegalStateException e) {
                e.printStackTrace();
            }

        }

        @Override
        public void onConfigureFailed(CameraCaptureSession session) {

        }
    }
}

DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
int width = metric.widthPixels; // 屏幕宽度(像素)
int height = metric.heightPixels; // 屏幕高度(像素)
final Camera2Helper camera2Helper=new Camera2Helper(CameraCharacteristics.LENS_FACING_BACK,surfaceView);
camera2Helper.setWidth(width);
camera2Helper.setHeight(height);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
camera2Helper.switchCamera();
}
});

参考链接:https://www.jianshu.com/p/d83161e77e90

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值