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
}
}
})