CameraX让实现Camera更简单

前段时间,突然看到一篇文章说CameraX,了解了一番,发现这功能真好,能帮我们节省好多工作量,以前我们写Camera功能需要使用Camera2,要处理SufraceView相关的一堆东西,还有旋转、预览尺寸跟画面尺寸的选择,各品牌手机设备上的兼容性,搞不好就变形了,没上百行甚至几千行代码绝对搞不定,Google也意识到了这个问题,CameraX 正是为解决这个痛点而诞生的。

先看看官方对CameraX的定义:

更多说明可去参考官方文档:https://developer.android.google.cn/training/camerax

开始使用:

官方DEMO:camera-samples/CameraXBasic at main · android/camera-samples · GitHub

注意:CameraX最低支持API21,也就是5.0及以上,最新版对targetSdkVersion要求也比较高,最好能保持在31,支持AndroidX。

1 导入依赖

可查看CameraX的最新的版本

api "androidx.camera:camera-core:1.1.0-alpha12"

api "androidx.camera:camera-camera2:1.1.0-alpha12"

implementation "androidx.camera:camera-view:1.0.0-alpha32"

implementation "androidx.camera:camera-lifecycle:1.1.0-alpha12"

2 创建main.xml布局,引入PreviewView

<androidx.camera.view.PreviewView
    android:id="@+id/viewFinder"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

3 初始化相机

/**
     * 开始打开相机预览
     */
    public void buildUseCameraCases() {
        ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(getContext());
        cameraProviderFuture.addListener(new Runnable() {
            @Override
            public void run() {
                try {
                    mCameraProvider = cameraProviderFuture.get();
                    bindCameraUseCases();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, ContextCompat.getMainExecutor(getContext()));
    }

4 绑定拍照设置,获取ImageCapture对象


    private void bindCameraImageUseCases() {
        try {
            int screenAspectRatio = aspectRatio(DensityUtil.getScreenWidth(getContext()), DensityUtil.getScreenHeight(getContext()));
            int rotation = mCameraPreviewView.getDisplay().getRotation();
            CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(lensFacing).build();
            // Preview
            Preview preview = new Preview.Builder()
                    .setTargetAspectRatio(screenAspectRatio)
                    .setTargetRotation(rotation)
                    .build();

            // ImageCapture
            mImageCapture = new ImageCapture.Builder()
                    .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
                    .setTargetAspectRatio(screenAspectRatio)
                    .setTargetRotation(rotation)
                    .build();

            // ImageAnalysis
            mImageAnalyzer = new ImageAnalysis.Builder()
                    .setTargetAspectRatio(screenAspectRatio)
                    .setTargetRotation(rotation)
                    .build();

            // Must unbind the use-cases before rebinding them
            mCameraProvider.unbindAll();
            // A variable number of use-cases can be passed here -
            // camera provides access to CameraControl & CameraInfo
            mCameraProvider.bindToLifecycle((LifecycleOwner) getContext(), cameraSelector, preview, mImageCapture, mImageAnalyzer);
            // Attach the viewfinder's surface provider to preview use case
            preview.setSurfaceProvider(mCameraPreviewView.getSurfaceProvider());
            // setFlashMode
            setFlashMode();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

5 执行拍照的方法

 ImageCapture.OutputFileOptions outputFileOptions =
            new ImageCapture.OutputFileOptions.Builder(new File(...)).build();
    imageCapture.takePicture(outputFileOptions, cameraExecutor,
        new ImageCapture.OnImageSavedCallback() {
            @Override
            public void onImageSaved(ImageCapture.OutputFileResults outputFileResults) {
                // insert your code here.
            }
            @Override
            public void onError(ImageCaptureException error) {
                // insert your code here.
            }
       }
    );

6 视频录制

和拍照一样,绑定录制设置,获取VideoCapture对象,执行录制方法

 private void bindCameraVideoUseCases() {
        try {
            CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(lensFacing).build();
            // Preview
            int rotation = mCameraPreviewView.getDisplay().getRotation();
            Preview preview = new Preview.Builder()
                    .setTargetRotation(rotation)
                    .build();
            // VideoCapture
            VideoCapture.Builder builder = new VideoCapture.Builder();
            builder.setTargetRotation(rotation);
            if (videoFrameRate > 0) {
                builder.setVideoFrameRate(videoFrameRate);
            }
            if (videoBitRate > 0) {
                builder.setBitRate(videoBitRate);
            }
            mVideoCapture = builder.build();
            // Must unbind the use-cases before rebinding them
            mCameraProvider.unbindAll();
            // A variable number of use-cases can be passed here -
            // camera provides access to CameraControl & CameraInfo
            mCameraProvider.bindToLifecycle((LifecycleOwner) getContext(), cameraSelector, preview, mVideoCapture);
            // Attach the viewfinder's surface provider to preview use case
            preview.setSurfaceProvider(mCameraPreviewView.getSurfaceProvider());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 mVideoCapture.startRecording(fileOptions, ContextCompat.getMainExecutor(getContext()),
                        new VideoCapture.OnVideoSavedCallback() {
                            @Override
                            public void onVideoSaved(@NonNull @NotNull VideoCapture.OutputFileResults outputFileResults) {
                                long minSecond = recordVideoMinSecond <= 0 ? CustomCameraConfig.DEFAULT_MIN_RECORD_VIDEO : recordVideoMinSecond;
                                if (recordTime < minSecond || outputFileResults.getSavedUri() == null) {
                                    return;
                                }
                                Uri savedUri = outputFileResults.getSavedUri();
                               
                            }

                            @Override
                            public void onError(int videoCaptureError, @NonNull @NotNull String message,
                                                @Nullable @org.jetbrains.annotations.Nullable Throwable cause) {
                              
                            }
                        });
 

关于特效方面,CameraX 提供了一个 Extensions API,用于使用制造商在各种 Android 设备(手机、平板电脑等)上实现的特效,但因为国内各厂商的定制,有一些特效还是不能通用的。

 好了关于CameraX的介绍就到此为止,还有更多的功能细节需要自己去开发研究,学无止境。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值