笔记 camearX基本使用

public class CaptureActivity extends BaseActivity {

    //设置使用后置摄像头
    private CameraX.LensFacing mLensFacing = CameraX.LensFacing.BACK;
    //设置旋转角度
    private int rotation_0=Surface.ROTATION_0;
    //设置分辨率
    private Size resolution = new Size(1280, 720);
    //设置宽高比
    private Rational rational = new Rational(9, 16);
    //预览
    private Preview preview;
    //拍照
    private ImageCapture imageCapture;
    //视频录制
    private VideoCapture videoCapture;
    private ActivityLayoutCaptureBinding binding;
    //记录是拍照还是录制视频
    private boolean takingPicture;
    //照片或视频存放路径
    private String path;
    public static final int REQ_CAPTURE = 10001;


    public static final String RESULT_FILE_PATH = "file_path";
    public static final String RESULT_FILE_WIDTH = "file_width";
    public static final String RESULT_FILE_HEIGHT = "file_height";
    public static final String RESULT_FILE_TYPE = "file_type";


    public static void startActivityForResult(Activity activity) {
        Intent intent = new Intent(activity, CaptureActivity.class);
        activity.startActivityForResult(intent, REQ_CAPTURE);
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = DataBindingUtil.setContentView(this, R.layout.activity_layout_capture);
//        申请权限验证================省略==============================================================
			//初始化
            bindCameraX();
		//点击拍摄按钮
        binding.recordview.setOnRecordListener(new RecordView.onRecordListener() {
            @Override
            public void onClick() {
                takingPicture=true;
                File file=new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
                        System.currentTimeMillis() + ".jpeg");

                //相机拍照 参数1 文件存储地址 参数2 拍照完成后的回调
                imageCapture.takePicture(file, new ImageCapture.OnImageSavedListener() {
                    //此接口在子线程内
                    @Override
                    public void onImageSaved(@NonNull File file) {
                            onFileSave(file);
                    }

                    @Override  //此接口在子线程内
                    public void onError(@NonNull ImageCapture.UseCaseError useCaseError, @NonNull String message, @Nullable Throwable cause) {
                        Log.i("message","拍照失败"+message);
                    }
                });
            }

            @SuppressLint("RestrictedApi")
            @Override
            public void onLongClick() {

                takingPicture = false;
                File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
                        System.currentTimeMillis() + ".mp4");
                
                // 录制视频 参数1文件保存地址 参数2回调接口
                videoCapture.startRecording(file, new VideoCapture.OnVideoSavedListener() {
                    @Override //此接口在子线程内
                    public void onVideoSaved(File file) {
                        onFileSave(file);

                    }

                    @Override  //此接口在子线程内
                    public void onError(VideoCapture.UseCaseError useCaseError, String message, @Nullable Throwable cause) {
                            Log.i("message","录制失败"+message);
                    }
                });

            }

            @SuppressLint("RestrictedApi")
            @Override
            public void onFinish() {
            	//结束录制
                videoCapture.stopRecording();
            }
        });

    }

    @SuppressLint("RestrictedApi")
    private void bindCameraX()
    {
        CameraX.unbindAll();
        //查询一下当前要使用的设备摄像头(比如后置摄像头)是否存在
        boolean hasAvailableCameraId = false;
        try {
            hasAvailableCameraId = CameraX.hasCameraWithLensFacing(mLensFacing);
        } catch (CameraInfoUnavailableException e) {
            e.printStackTrace();
        }

        if (!hasAvailableCameraId) {
            Toast.makeText(this,"无可用的设备cameraId!,请检查设备的相机是否被占用",Toast.LENGTH_SHORT);
            finish();
            return;
        }

        //查询一下是否存在可用的cameraId.形式如:后置:"0",前置:"1"
        String cameraIdForLensFacing = null;
        try {
            cameraIdForLensFacing = CameraX.getCameraFactory().cameraIdForLensFacing(mLensFacing);
        } catch (CameraInfoUnavailableException e) {
            e.printStackTrace();
        }
        if (TextUtils.isEmpty(cameraIdForLensFacing)) {
            Toast.makeText(this,"无可用的设备cameraId!,请检查设备的相机是否被占用",Toast.LENGTH_SHORT);
            finish();
            return;
        }

        PreviewConfig config= new PreviewConfig.Builder()
                //设置使用前置还是后置摄像头
                .setLensFacing(mLensFacing)
                //设置旋转角度
                .setTargetRotation(rotation_0)
                //设置预览时分辨率
                .setTargetResolution(resolution)
                //设置屏幕宽高比 9:16
                .setTargetAspectRatio(rational).build();
        preview = new Preview(config);

        imageCapture = new ImageCapture(new ImageCaptureConfig.Builder()
                    .setTargetResolution(resolution)
                    .setTargetAspectRatio(rational)
                    .setLensFacing(mLensFacing)
                    .setTargetRotation(rotation_0).build());

        videoCapture = new VideoCapture(new VideoCaptureConfig.Builder()
                        .setTargetRotation(rotation_0)
                        .setTargetAspectRatio(rational)
                        .setLensFacing(mLensFacing)
                        .setTargetResolution(resolution)
                        //设置比特率
                        .setBitRate(3*1024*1024)
                        //设置帧率
                        .setVideoFrameRate(25).build());
        //视频流的每一帧会回调到这个方法
        preview.setOnPreviewOutputUpdateListener(new Preview.OnPreviewOutputUpdateListener() {
            @Override
            public void onUpdated(Preview.PreviewOutput output) {
                //要先从父布局移除然后再添加进来才能正确渲染
                TextureView textureView = binding.textureView;
                ViewGroup viewGroup=(ViewGroup)textureView.getParent();
                viewGroup.removeView(textureView);
                viewGroup.addView(textureView,0);
                textureView.setSurfaceTexture(output.getSurfaceTexture());
            }
        });
        //上面配置的都是我们期望的分辨率
        List<UseCase> newUseCase=new ArrayList<>();
        newUseCase.add(preview);
        newUseCase.add(imageCapture);
        newUseCase.add(videoCapture);
        //下面我们要查询一下 当前设备它所支持的分辨率有哪些,然后再更新一下 所配置的几个usecase
        Map<UseCase, Size> resolutions = CameraX.getSurfaceManager().
                getSuggestedResolutions(cameraIdForLensFacing, null, newUseCase);

        Iterator<Map.Entry<UseCase, Size>> iterator = resolutions.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<UseCase, Size> next = iterator.next();
            UseCase useCase = next.getKey();
            Size value = next.getValue();
            Map<String, Size> update = new HashMap<>();
            update.put(cameraIdForLensFacing, value);
            useCase.updateSuggestedResolution(update);
        }


        CameraX.bindToLifecycle(this,preview,imageCapture,videoCapture);
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.i("requsetnnn",requestCode+","+resultCode);
        if (requestCode==PreviewActivity.REQ_PREVIEW&&resultCode==RESULT_OK)
        {
            Intent intent=new Intent();
            intent.putExtra(RESULT_FILE_PATH,path);
            //当设备处于竖屏情况时,宽高的值 需要互换,横屏不需要
            intent.putExtra(RESULT_FILE_WIDTH, resolution.getHeight());
            intent.putExtra(RESULT_FILE_HEIGHT, resolution.getWidth());
            intent.putExtra(RESULT_FILE_TYPE, !takingPicture);
            setResult(RESULT_OK, intent);
            finish();
        }
    }

    private void onFileSave(File file) {
        path = file.getAbsolutePath();
        String taketype=takingPicture?"image/jpeg":"video/mp4";
        //扫描文件
        MediaScannerConnection.scanFile(this,new String[]{path},new String[]{taketype},null);
        binding.recordview.PostInvalidate();
        PreviewActivity.startActivityForResult(this,path,!takingPicture,"完成");
    }

    @Override
    protected void onDestroy() {
        CameraX.unbindAll();
        binding.recordview.PostInvalidate();
        super.onDestroy();

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值