Android使用CameraX打开相机拍照简单使用

1.首先是效果图

 2.布局及依赖

布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/take"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="拍照"
        android:onClick="startTake"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <androidx.camera.view.PreviewView
        android:id="@+id/surfacePreview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <ImageView
        android:id="@+id/ivPic"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_width="200dp"
        android:layout_height="200dp"/>

</androidx.constraintlayout.widget.ConstraintLayout>

依赖:

    def camerax_version = "1.0.0-beta03"
// CameraX core library using camera2 implementation
    implementation "androidx.camera:camera-camera2:$camerax_version"
// CameraX Lifecycle Library
    implementation "androidx.camera:camera-lifecycle:$camerax_version"
// CameraX View class
    implementation "androidx.camera:camera-view:1.0.0-alpha10"

3.activity

kotlin方式:

package com.xtm.camerademo

import android.Manifest
import android.content.pm.PackageManager
import android.graphics.BitmapFactory
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.ImageView
import android.widget.Toast
import androidx.camera.core.*
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import java.io.File

class MainActivity : AppCompatActivity() {
    private lateinit var imageCapture: ImageCapture
    private var takePic: Button? = null
    private var ivPick: ImageView? = null
    private var surfacePreview: PreviewView? = null
    private lateinit var camera: Camera
    private lateinit var preview: Preview
    private val REQ_CODE:Int = 1
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initView()
        initData()
    }

    private fun initView() {
        surfacePreview = findViewById<PreviewView>(R.id.surfacePreview)
        takePic = findViewById<Button>(R.id.take)
        ivPick = findViewById<ImageView>(R.id.ivPic)

    }

    private fun initData() {
        // 检查相机权限
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            println("===>需要权限")
            if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
                println("===>shouldShowRequestPermissionRationale")
            } else {
                println("===>not shouldShowRequestPermissionRationale")
            }
            ActivityCompat.requestPermissions(this,arrayOf(Manifest.permission.CAMERA),REQ_CODE)
        } else {
            println("===>已经获取到了权限")
            startCamera();
        }

    }

    /**
     * 打开相机并预览
     */
    private fun startCamera() {
        println("打开相机")
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

        // 设置预览
        preview = Preview.Builder().build()  //  UseCase子类Preview
        // 设置拍照
        imageCapture = ImageCapture.Builder().build()// UseCase子类ImageCapture

        // 设置打开的相机(前置/后置)
        val cameraSelector =
            CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build()

        try {
            // 解除相机之前的所有绑定
            cameraProvider.unbindAll()
            // 绑定前面用于预览和拍照的UseCase到相机上
            camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture)
            // 设置用于预览的view
            preview?.setSurfaceProvider(surfacePreview?.createSurfaceProvider(camera?.cameraInfo))
        } catch (exc: Exception) {
            println("Use case绑定失败")
        }

    }

    /**
     * 拍照
     */
    private fun takePhoto() {
        // 拍照保存路径
        val imagePath =
            filesDir.absolutePath + "/test.jpg"// 因为这里是内部文件不需要动态申请内存卡读写权限,这里不能有子目录,否则出错:比如+“/pic/test.jpg”
        val file = File(imagePath);
        val outputOptions = ImageCapture.OutputFileOptions.Builder(file).build()
        // 开始拍照
        imageCapture.takePicture(
            outputOptions,
            ContextCompat.getMainExecutor(this),
            object : ImageCapture.OnImageSavedCallback {
                override fun onError(exc: ImageCaptureException) {
                    println("Photo capture failed: ${exc.message}")
                }

                override fun onImageSaved(output: ImageCapture.OutputFileResults) {
                    val savedUri = Uri.fromFile(file)
                    val msg = "Photo capture succeeded: $savedUri"
                    Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
                    println(msg)
                    // 显示拍照内容
                    ivPick?.setImageBitmap(BitmapFactory.decodeFile(file.absolutePath))
                }
            })
    }

    /**
     * 点击拍照按钮
     */
    fun startTake(view: View) {
        takePhoto()
    }

    override fun onRequestPermissionsResult(requestCode: Int,permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQ_CODE && grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            startCamera()
            println("权限获取成功")
        } else {
            println("你拒绝了权限")
        }
    }


}

java方式:



import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
import androidx.camera.core.Preview;
import androidx.camera.core.ImageCapture.OnImageSavedCallback;
import androidx.camera.core.ImageCapture.OutputFileOptions;
import androidx.camera.core.ImageCapture.OutputFileResults;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.common.util.concurrent.ListenableFuture;
import com.ybzl.big_refrigerator.R;

import java.io.File;
import java.util.concurrent.ExecutionException;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public final class CameraTestActivity extends AppCompatActivity {
   private ImageCapture imageCapture;
   private Button takePic;
   private ImageView ivPick;
   private PreviewView surfacePreview;
   private Camera camera;
   private Preview preview;
   private final int REQ_CODE = 1;

   protected void onCreate(@Nullable Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_camera_test);
      initView();
      this.initData();
   }

   private void initView() {
      surfacePreview = findViewById(R.id.surfacePreview);
      takePic = findViewById(R.id.take);
      ivPick = findViewById(R.id.ivPic);

   }

   private final void initData() {
      String var1;
      boolean var2;
      if (ContextCompat.checkSelfPermission((Context)this, "android.permission.CAMERA") != 0) {
         var1 = "===>需要权限";
         var2 = false;
         System.out.println(var1);
         if (ActivityCompat.shouldShowRequestPermissionRationale((Activity)this, "android.permission.CAMERA")) {
            var1 = "===>shouldShowRequestPermissionRationale";
            var2 = false;
            System.out.println(var1);
         } else {
            var1 = "===>not shouldShowRequestPermissionRationale";
            var2 = false;
            System.out.println(var1);
         }

         ActivityCompat.requestPermissions((Activity)this, new String[]{"android.permission.CAMERA"}, this.REQ_CODE);
      } else {
         var1 = "===>已经获取到了权限";
         var2 = false;
         System.out.println(var1);
         this.startCamera();
      }

   }

   private final void startCamera() {
      System.out.println("打开相机");
      ListenableFuture<ProcessCameraProvider>  cameraProviderFuture = ProcessCameraProvider.getInstance(this);
      ProcessCameraProvider cameraProvider = null;
      try {
         cameraProvider = cameraProviderFuture.get();
         // 设置预览
         preview = new Preview.Builder().build() ; //  UseCase子类Preview
         // 设置拍照
         imageCapture = new ImageCapture.Builder().build();// UseCase子类ImageCapture

         // 设置打开的相机(前置/后置)
         CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();

         try {
            // 解除相机之前的所有绑定
            cameraProvider.unbindAll();
            // 绑定前面用于预览和拍照的UseCase到相机上
            camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture);
            // 设置用于预览的view
            if(preview!=null && surfacePreview!=null && camera!=null){
               preview.setSurfaceProvider(surfacePreview.createSurfaceProvider(camera.getCameraInfo()));
            }

         } catch (Exception e) {
            System.out.println("Use case绑定失败");
         }
      } catch (ExecutionException e) {
         e.printStackTrace();
      } catch (InterruptedException e) {
         e.printStackTrace();
      }

   }

   private final void takePhoto() {
      // 拍照保存路径
      String imagePath = getFilesDir().getAbsolutePath() + "/test.jpg";// 因为这里是内部文件不需要动态申请内存卡读写权限,这里不能有子目录,否则出错:比如+“/pic/test.jpg”
      File file = new File(imagePath);
      OutputFileOptions outputOptions = new ImageCapture.OutputFileOptions.Builder(file).build();
      // 开始拍照
      imageCapture.takePicture(outputOptions, ContextCompat.getMainExecutor(this),
              new OnImageSavedCallback() {
                 @Override
                 public void onImageSaved(@NonNull @NotNull OutputFileResults outputFileResults) {
                    Uri savedUri = Uri.fromFile(file);
                    String msg = "Photo capture succeeded: "+savedUri;
                    Toast.makeText(getApplication(), msg, Toast.LENGTH_SHORT).show();
                    // 显示拍照内容
                    if(ivPick!=null){
                       ivPick.setImageBitmap(BitmapFactory.decodeFile(file.getAbsolutePath()));
                    }

                 }

                 @Override
                 public void onError(@NonNull @NotNull ImageCaptureException exception) {
                    System.out.println(exception.getImageCaptureError());
                 }
              });
   }


   /**
    * 点击拍照按钮
    */
   public void startTake(View view) {
      takePhoto();
   }

   @Override
   public void onRequestPermissionsResult(int requestCode, @NonNull @NotNull String[] permissions, @NonNull @NotNull int[] grantResults) {
      super.onRequestPermissionsResult(requestCode, permissions, grantResults);
      if (requestCode == REQ_CODE && grantResults!=null && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
         startCamera();
         System.out.println("权限获取成功");
      } else {
         System.out.println("你拒绝了权限");
      }
   }



}

4.清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xtm.camerademo">

    <uses-feature android:name="android.hardware.camera.any" />
    <uses-permission android:name="android.permission.CAMERA" />


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.CameraDemo">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

使用 CameraX 调用系统相机需要进行以下配置: 1. 在项目的 build.gradle 文件中添加以下依赖项: ``` dependencies { def camerax_version = "1.0.0-beta01" // CameraX core library implementation "androidx.camera:camera-core:$camerax_version" // CameraX Camera2 extensions implementation "androidx.camera:camera-camera2:$camerax_version" // CameraX Lifecycle library implementation "androidx.camera:camera-lifecycle:$camerax_version" // CameraX View class implementation "androidx.camera:camera-view:1.0.0-alpha08" } ``` 2. 在 AndroidManifest.xml 文件中添加以下权限: ``` <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> ``` 3. 在布局文件中添加 CameraView: ``` <androidx.camera.view.CameraView android:id="@+id/camera_view" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 4. 在 Activity 或 Fragment 中配置 CameraX: ``` // 获取 CameraView 引用 val cameraView = findViewById<CameraView>(R.id.camera_view) // 配置 Preview val preview = Preview.Builder() .build() .also { it.setSurfaceProvider(cameraView.surfaceProvider) } // 配置 ImageCapture val imageCapture = ImageCapture.Builder() .build() // 配置 ImageAnalysis val imageAnalyzer = ImageAnalysis.Builder() .build() .also { it.setAnalyzer(cameraExecutor, LuminosityAnalyzer()) } // 绑定生命周期 CameraX.bindToLifecycle(this, preview, imageCapture, imageAnalyzer) ``` 其中,CameraExecutor 是一个 Executor 对象,可以使用以下方式创建: ``` private val cameraExecutor = Executors.newSingleThreadExecutor() ``` 5. 调用 ImageCapture.takePicture() 方法拍照,调用 ImageAnalysis.setAnalyzer() 方法进行图像分析。 以上是使用 CameraX 调用系统相机的基本配置方法,可以根据需要进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值