CameraX 一:拍照、预览

什么是CameraX?

CameraX是一个基于camera2的加强库,具有生命周期感知能力,有很多的自感知能力,比如我们不需要处理拍照旋转,它向后兼容至21.

有没有必要升级到CameraX?

现在,你只需要两行代码就能实现与预安装的相机相同的体验和功能(what)

有生命周期感知能力

更简单的使用方式

自动解决设备的兼容性问题,减少代码量,比如自动确定可使用的最佳分辨率。包括其他宽高比、屏幕方向、旋转角度、预览大小,这些都交给CameraX

反正有意思的东西我就必须要学。。

我的计划大概是分为

预览与拍照(测试机Android 11)

CameraX是一个jatpack支持库,使用它我们需要导入依赖。

 // CameraX core library using the camera2 implementation
    def camerax_version = "1.0.0"
    // The following line is optional, as the core library is included indirectly by camera-camera2
    implementation("androidx.camera:camera-core:${camerax_version}")
    implementation("androidx.camera:camera-camera2:${camerax_version}")
    // If you want to additionally use the CameraX Lifecycle library
    implementation("androidx.camera:camera-lifecycle:${camerax_version}")
    // If you want to additionally use the CameraX View class
    implementation("androidx.camera:camera-view:1.0.0-alpha25")
    // If you want to additionally use the CameraX Extensions library
    implementation("androidx.camera:camera-extensions:1.0.0-alpha25")

记得处理CAMERA权限。

    <Button
        android:id="@+id/takeP"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="拍照" />

    <androidx.camera.view.PreviewView
        android:id="@+id/previewView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <ImageView
        android:layout_width="match_parent"
        android:id="@+id/imageView"
        android:layout_height="0dp"
        android:layout_weight="1" />

我们准备了三个按钮,拍照、预览、显示拍照后图片,大概这样:

获取ProcessCameraProvider,它的作用是将相机的生命周期绑定到应用程序,它是一个单例类。

 private fun initCamera() {
        cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        //请求 CameraProvider 后,请验证它能否在视图创建后成功初始化。以下代码展示了如何执行此操作:
        cameraProviderFuture.addListener(Runnable {
            val cameraProvider = cameraProviderFuture.get()
            bindPreview(cameraProvider)
        }, ContextCompat.getMainExecutor(this))
    }

获取camera

     fun bindPreview(cameraProvider: ProcessCameraProvider) {
        var preview: Preview = Preview.Builder()
            .setTargetResolution(Size(1280, 720)) //设置分辨率
            .build()

//        拍照
        imageCapture = ImageCapture.Builder()
            .setCaptureMode(CAPTURE_MODE_MAXIMIZE_QUALITY) //优先考虑图片质量,速度略低
//            .setTargetRotation(Surface.ROTATION_90)
            .build()

        var cameraSelector: CameraSelector = CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK) //后置
            .build()

        //提供previewView预览控件
        preview.setSurfaceProvider(previewView.surfaceProvider)

        var camera = cameraProvider.bindToLifecycle(
            this as LifecycleOwner,
            cameraSelector,
            imageCapture,
            preview
        )
    }

现在运行,你将看到可以正常显示预览界面,如果没有显示,请检查是否处理危险权限CAMERA。

添加拍照的点击事件

 private fun takePicture() {
        val file = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES)!!.path, "1.jpg")
       
        Log.d(TAG, "initView: 拍照")
        val options = ImageCapture.OutputFileOptions.Builder(file).build()

        imageCapture?.takePicture(options, mainExecutor,
            object : ImageCapture.OnImageSavedCallback {
                override fun onError(error: ImageCaptureException) {
                    // insert your code here.
                    Log.d(TAG, "onError: " + error.message)
                }

                override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
                    // insert your code here.
                    Log.d(TAG, "onImageSaved: ")
                    val savedUri = outputFileResults.savedUri ?: Uri.fromFile(file)
                    imageView.setImageURI(null)
                    imageView.setImageURI(savedUri)
                }
            })
    }

这里我使用了外部存储目录,保存在storage/emulated/0/android/data/packageName/下,如果你要保存在公共区域,可修改如下代码,或者你将直接处理图片数据,ImageCapture.OutputFileOptions.Builder的构造函数的参数,注意修改。

 ContentValues contentValues = new ContentValues();
 contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "NEW_IMAGE");
 contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
 ImageCapture.OutputFileOptions options = new ImageCapture.OutputFileOptions.Builder(
         getContentResolver(),
         MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
         contentValues).build();

现在点击按钮,拍照的图片将显示在ImageView上,我们没有处理旋转角度,预览角度,CameraX帮我们自动处理了这些。

在这里插入图片描述

下一篇我们使用CameraX自带的VideoCapture实现自带的录制视频功能。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
Camerax是Android相机框架的一部分,它提供了便捷的API来实现相机预览拍照功能。 要使用Camerax进行预览拍照,我们首先需要配置相机权限。在AndroidManifest.xml文件中,添加以下权限: ``` <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ``` 接下来,在activity的布局文件中添加一个预览用的TextureView: ``` <TextureView android:id="@+id/previewView" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 在相关的Activity中,我们使用Camerax来实现预览拍照功能。首先,在onCreate方法中初始化Camerax的实例: ``` PreviewConfig previewConfig = new PreviewConfig.Builder().build(); Preview preview = new Preview(previewConfig); ImageCaptureConfig captureConfig = new ImageCaptureConfig.Builder().build(); ImageCapture imageCapture = new ImageCapture(captureConfig); CameraX.bindToLifecycle(this, preview, imageCapture); ``` 然后,我们需要将预览显示在TextureView中: ``` TextureView previewView = findViewById(R.id.previewView); preview.setSurfaceProvider(previewView.getSurfaceProvider()); ``` 最后,我们可以在需要的时候进行拍照: ``` // 通过点击按钮触发拍照 Button captureButton = findViewById(R.id.captureButton); captureButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { File file = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "IMG_" + System.currentTimeMillis() + ".jpg"); ImageCapture.OutputFileOptions outputFileOptions = new ImageCapture.OutputFileOptions.Builder(file).build(); imageCapture.takePicture(outputFileOptions, ContextCompat.getMainExecutor(MainActivity.this), new ImageCapture.OnImageSavedCallback() { @Override public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) { // 在此处对拍照后的图片进行处理 } @Override public void onError(@NonNull ImageCaptureException exception) { // 拍照出现错误时的处理 } }); } }); ``` 通过以上步骤,我们就可以使用Camerax来实现Android相机的预览拍照功能。它提供了简单而强大的API,使得实现相机应用变得更加容易。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值