iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 27
1
Mobile Development

Kotlin Android Jetpack 系列 第 27

{Day27}CameraX

CameraX

CameraX提供了API,可在大多數Android設備上使用。

ProcessCameraProvider.getInstance(this):獲取相機提供者。
Preview.Builder().build():創建預覽類。
ImageCapture.Builder().build():創建拍照類。
ProcessCameraProvider.getInstance(this).bindToLifecycle(this, "相機鏡頭方向", preview, imageCapture):綁定相機需要的功能。
apply plugin: 'kotlin-android-extensions'

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    def camerax_version = "1.0.0-beta10"
    implementation "androidx.camera:camera-camera2:$camerax_version"
    implementation "androidx.camera:camera-lifecycle:$camerax_version"
    implementation "androidx.camera:camera-view:1.0.0-alpha17"
    implementation 'androidx.activity:activity-ktx:1.2.0-beta01'
    implementation 'androidx.fragment:fragment:1.3.0-beta01'
}

布局

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

    <Button
        android:id="@+id/camera_capture_button"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginBottom="50dp"
        android:text="拍照"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />

    <androidx.camera.view.PreviewView
        android:id="@+id/viewBinder"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
           
    <ImageView
        android:visibility="gone"
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#ffffff"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

取得相機權限

private var imageCapture: ImageCapture? = null
private var outputDirectory: File? = null
private val permission = registerForActivityResult(ActivityResultContracts.RequestPermission()){
    if (it) {
        Log.d("GOGO", "取得")
    } else {
        Log.d("GOGO", "未取得")
    }
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    //取得相機權限
    permission.launch(Manifest.permission.CAMERA)
    outputDirectory = getExternalFilesDir("camera")
}

設置相機功能

val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener(Runnable {
      val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

      //創建預覽
      val preview = Preview.Builder()
             .build()
             .also { it.setSurfaceProvider(viewBinder.surfaceProvider) }
                    
      //創建拍照
      imageCapture = ImageCapture.Builder().build()

      //鏡頭方向
      val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
      cameraProvider.unbindAll()

      //綁定預覽View並設置鏡頭
      cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture)
}, ContextCompat.getMainExecutor(this))

拍照

val imageCapture = imageCapture ?: return

//檔案名稱與儲存路徑
val photoFile = File(outputDirectory, SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS", Locale.TAIWAN)
.format(System.currentTimeMillis()) + ".jpg")

val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build()

imageCapture.takePicture(outputOptions, ContextCompat.getMainExecutor(this),
     object : ImageCapture.OnImageSavedCallback {
        override fun onError(exc: ImageCaptureException) {

        }

        override fun onImageSaved(output: ImageCapture.OutputFileResults) {
           val savedUri = Uri.fromFile(photoFile)
           var bitmap = MediaStore.Images.Media.getBitmap(contentResolver, savedUri)
           //翻轉圖片
           if (bitmap.width > bitmap.height) {
               val matrix = Matrix()
               matrix.setRotate(90f)
               bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
           }

            imageView.setImageBitmap(bitmap)
            imageView.visibility = View.VISIBLE
            imageView.setOnClickListener {
                imageView.visibility = View.GONE
            }
         }
})


上一篇
{Day26}Activity
下一篇
{Day28}Biometric
系列文
Kotlin Android Jetpack 30

尚未有邦友留言

立即登入留言