Android camera2

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/danfengw/article/details/78745433

这里写图片描述
布局只用到了SurfaceView跟Button。有的手机黑屏,需要给SurfaceViewHolder设置FixedSize。

public class CameraActivity extends AppCompatActivity implements SurfaceHolder.Callback {
    private SurfaceView mCameraSurfaceView;
    private SurfaceHolder mSurfaceHolder;
    //相机相关代码,三个必须的
    private CameraManager mCameraManager;
    private CameraDevice mCameraDevice;
    private CameraCaptureSession mCameraCaptureSession;
    //阻止相机关闭前退出app
    private Semaphore mCameraOpenCloseLock = new Semaphore(1);
    //摄像头id  0:后摄像头 1:前摄像头
    private static final String mCameraId = "" + CameraCharacteristics.LENS_FACING_FRONT;
    //opencamera方法中需要ImageReader和handler
    private ImageReader mImageReader;
    private Handler mHandler;
    private Size previewsize;
    private ImageReader.OnImageAvailableListener mImageAvailableListenter = new ImageReader.OnImageAvailableListener() {
        @SuppressLint("NewApi")
        @Override
        public void onImageAvailable(ImageReader reader) {
            mCameraDevice.close();
            //这里获取到图片数据
           ……

        }
    };

    private static final SparseIntArray ORIENTATIONS = new SparseIntArray();

    ///为了使照片竖直显示
    static {
        ORIENTATIONS.append(Surface.ROTATION_0, 90);
        ORIENTATIONS.append(Surface.ROTATION_90, 0);
        ORIENTATIONS.append(Surface.ROTATION_180, 270);
        ORIENTATIONS.append(Surface.ROTATION_270, 180);
    }

    /**
     * Max preview width that is guaranteed by Camera2 API
     */
    private static final int MAX_PREVIEW_WIDTH = 1920;

    /**
     * Max preview height that is guaranteed by Camera2 API
     */
    private static final int MAX_PREVIEW_HEIGHT = 1080;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);
        initView();
        initSurfaceView();
    }

    private void initView() {
        mCameraSurfaceView = (SurfaceView) findViewById(R.id.camera_surfaceview);
        mFrameIv = (ImageView) findViewById(R.id.frame_imageview);
        mTakePhotoBt = (Button) findViewById(R.id.takephoto_bt);
        mFocusView = findViewById(R.id.focus_index);

    }

    private void initSurfaceView() {
        mCameraSurfaceView.setBackgroundColor(TRIM_MEMORY_BACKGROUND);
        mSurfaceHolder = mCameraSurfaceView.getHolder();
        mSurfaceHolder.setKeepScreenOn(true);
        mSurfaceHolder.addCallback(this);
    }


    @Override
    protected void onResume() {
        mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
//这里可以设置也可以不设置,使用过程中发现有的手机不设置这个时会出现黑屏现象
        mSurfaceHolder.setFixedSize(800, 600);
        super.onResume();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {

 //不设置holder的Fixedsize时设置initCamera2(mCameraSurfaceView.getWidth(),mCameraSurfaceView.getHeight());
            initCamera2(800, 600);         

    }

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

    }

    @SuppressLint("NewApi")
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (mCameraDevice != null) {
            mCameraDevice.close();
        }
    }

    @SuppressLint("NewApi")
    private void initCamera2(int width, int height) {
        if (checkCameraPermission()) {
            try {
                String camerId = mCameraManager.getCameraIdList()[0];
                CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(camerId);
                StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                previewsize = map.getOutputSizes(SurfaceTexture.class)[0];
                HandlerThread handlerthread = new HandlerThread("Camera2");
                handlerthread.start();
                mHandler = new Handler(handlerthread.getLooper());
                mImageReader = ImageReader.newInstance(width, height, ImageFormat.JPEG,  /*maxImages*/2);
                mImageReader.setOnImageAvailableListener(mImageAvailableListenter, mHandler);
                mCameraManager.openCamera(mCameraId, mCameraDeviceCallBack, mHandler);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        } else {
            finish();
            return;
        }

    }

    private boolean checkCameraPermission() {
        if (ContextCompat.checkSelfPermission(getApplicationContext(),
                Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(getApplicationContext(), "没有相机权限", Toast.LENGTH_LONG).show();
            return false;
        } else {
            return true;
        }
    }


    @SuppressLint("NewApi")
    private CameraDevice.StateCallback mCameraDeviceCallBack = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(@NonNull CameraDevice camera) {
            try {
                //当相机被打开,该方法将被回调,因此再这里进行相机预览设置
                mCameraOpenCloseLock.release();
                mCameraDevice = camera;
                //开启预览
                createCameraCaptureSession();
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onDisconnected(@NonNull CameraDevice camera) {
            mCameraOpenCloseLock.release();
            if (mCameraDevice != null) {
                mCameraDevice.close();
                mCameraDevice = null;
            }
        }


        @Override
        public void onError(@NonNull CameraDevice camera, int error) {

        }
    };
    private CaptureRequest.Builder mCaptureRequestBuilder;

    @SuppressLint("NewApi")//开启预览
    private void createCameraCaptureSession() throws CameraAccessException {
        //创建预览需要的CaptureRequest.Builder
        mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        //添加surface为CaptureRequest.Builder的目标
        mCaptureRequestBuilder.addTarget(mSurfaceHolder.getSurface());
        //创建CameraCaptureSession该对象负责管理处理预览请求和拍照请求
        mCameraDevice.createCaptureSession(Arrays.asList(mSurfaceHolder.getSurface(),
                mImageReader.getSurface()), mSessionPreviewStateCallback, mHandler);
    }

    @SuppressLint("NewApi")
    private CameraCaptureSession.StateCallback mSessionPreviewStateCallback = new CameraCaptureSession.StateCallback() {
        @Override
        public void onConfigured(@NonNull CameraCaptureSession session) {
            try {
                //摄像头已经准备好,开始显示预览
                mCameraCaptureSession = session;
                //自动对焦
                mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                //打开闪光灯
//                mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
                //显示预览
                CaptureRequest previewRequest = mCaptureRequestBuilder.build();
                mCameraCaptureSession.setRepeatingRequest(previewRequest, null, mHandler);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onConfigureFailed(@NonNull CameraCaptureSession session) {
            Log.e("Camera2", "相机预览失败");
        }
    };
//


    public void takePicture(View view) {
        takePic();
    }

    @SuppressLint("NewApi")
    public void takePic() {
        if (mCameraDevice == null) return;
        // 创建拍照需要的CaptureRequest.Builder
        try {
            // 将imageReader的surface作为CaptureRequest.Builder的目标
            mCaptureRequestBuilder.addTarget(mImageReader.getSurface());
            // 自动对焦
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            // 自动曝光
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
            // 获取手机方向
            int rotation = getWindowManager().getDefaultDisplay().getRotation();
            // 根据设备方向计算设置照片的方向
            mCaptureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
            //拍照
            CaptureRequest mCaptureRequest = mCaptureRequestBuilder.build();
            mCameraCaptureSession.capture(mCaptureRequest, null, mHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

}
阅读更多 登录后自动展开
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页