Android camera2

来源:互联网 发布:中国税务网络大学入口 编辑:程序博客网 时间:2024/05/17 20:31

这里写图片描述
布局只用到了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();        }    }}
原创粉丝点击