- 总览
- Integration
- Preview
- 图像分析
- Image Analysis with ML kit
- Image Capture
- Extensions
总览
CameraX是目前位于Alpha中的Jetpack支持库。CameraX库旨在简化应用程序开发中相机功能的使用。CameraX通过“ 图像分析”提供了对相机的深入分析,还提供了通过扩展使用内置设备相机功能(如HDR,人像模式等)的方法。
CameraX中有一个称为用例的概念,它通过使用特定用例而不是专注于管理所有特定于设备的细微差别来增强开发人员的交互。
共有三个用例,它们是
无论您使用的是哪种操作系统或设备,CameraX均通过摄像头界面为开发人员提供一致的行为
话虽如此,CameraX在Alpha中,请注意,尚不适合在生产应用中使用。
Integration
CameraX库向后兼容Android L,也就是说,将以下行添加到build.gradle文件中,您很高兴
dependencies {
// CameraX core library
def camerax_version = "1.0.0-alpha06"
// CameraX view library
def camerax_view_version = "1.0.0-alpha03"
// CameraX extensions library
def camerax_ext_version = "1.0.0-alpha03"
implementation "androidx.camera:camera-core:$camerax_version"
// If you want to use Camera2 extensions
implementation "androidx.camera:camera-camera2:$camerax_version"
// If you to use the Camera View class
implementation "androidx.camera:camera-view:$camerax_view_version"
// If you to use Camera Extensions
implementation "androidx.camera:camera-extensions:$camerax_ext_version"
}
Preview
预览用例提供了[**TextureView**](https://developer.android.com/reference/android/view/TextureView)
流媒体输出相机的位置。让我们看看如何[**TextureView**](https://developer.android.com/reference/android/view/TextureView)
在我们的布局中创建一个
<?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"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextureView
android:id="@+id/view_finder"
android:layout_width="600px"
android:layout_height="800px"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
在这里,我们使用600 * 800分辨率的Textureview,它还提供了其他信息以供裁剪,缩放或旋转视图以正确显示。现在让我们看一下编码部分
// Create configuration object for the viewfinder use case
val previewConfig = PreviewConfig.Builder().apply {
setTargetAspectRatio(AspectRatio.RATIO_4_3)
}.build()
// Build the viewfinder use case
val preview = Preview(previewConfig)
// Every time the viewfinder is updated, recompute layout
preview.setOnPreviewOutputUpdateListener {
// To update the SurfaceTexture, we have to remove it and r
val parent = view_finder.parent as ViewGroup
parent.removeView(view_finder)
parent.addView(view_finder, 0)
view_finder.surfaceTexture = it.surfaceTexture
updateTransform()
}
CameraX.bindToLifecycle(this,preview)
private fun updateTransform() {
val matrix = Matrix()
// Compute the center of the view finder
val centerX = view_finder.width / 2f
val centerY = view_finder.height / 2f
// Correct preview output to account for display rotation
val rotationDegrees = when (view_finder.display.rotation) {
Surface.ROTATION_0 -> 0
Surface.ROTATION_90 -> 90
Surface.ROTATION_180 -> 180
Surface.ROTATION_270 -> 270
else -> return
}
matrix.postRotate(-rotationDegrees.toFloat(), centerX, centerY)
// Finally, apply transformations to our TextureView
view_finder.setTransform(matrix)
}
图像分析
图像分析用例提供了一个几乎可访问的图像来进行图像处理,应用机器学习以及更多图像分析技术。让我们看一下图像分析用例的编码部分
val imageAnalysisConfig = ImageAnalysisConfig.Builder()
.setTargetResolution(Size(1280, 720))
.setImageReaderMode(ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE)
.build()
val imageAnalysis = ImageAnalysis(imageAnalysisConfig)
imageAnalysis.setAnalyzer(executor,ImageAnalysis.Analyzer { image, rotationDegrees ->
//your code here
})
CameraX.bindToLifecycle(this,imageAnalysis,preview)
CameraX with ML kit
如果您不熟悉Firebase的ML套件,请阅读以下文章
Android中的机器学习 如何在Android中使用Firebase ML Kit medium.com
话虽这么说,用ImageAnalysis。分析器获得一个ImageProxy,通过它我们可以获取图像并在ML套件中使用该虚拟图像,如下所示
imageAnalysis.setAnalyzer(executor,ImageAnalysis.Analyzer { image, rotationDegrees ->
image?.image?.let {
val image2 = FirebaseVisionImage.fromMediaImage(it,rotationDegrees)
val detector = FirebaseVision.getInstance() .onDeviceTextRecognizer
detector.processImage(image2)
.addOnSuccessListener { firebaseVisionText ->
Timber.v("Image_detection sucess %s", firebaseVisionText.text)
}
.addOnFailureListener {
// Task failed with an exception
Timber.v("Image_detection failed %s", it.message)
}
}
})
Image Capture
通过图像捕获,您可以用很少的代码就能保存高分辨率图像。
这是拍照的用例配置
val imageCaptureConfig = ImageCaptureConfig.Builder()
.setTargetAspectRatio(AspectRatio.RATIO_4_3)
.setCaptureMode(ImageCapture.CaptureMode.MIN_LATENCY)
.build()
val imageCapture = ImageCapture(imageCaptureConfig)
CameraX.bindToLifecycle(this as LifecycleOwner,
imageCapture, preview)
当我们设置好用例后,我们可以看到相机的预览,是时候拍照了
让我们看看如何做到
val file = File(
externalMediaDirs.first(),
"${System.currentTimeMillis()}.jpg")
imageCapture.takePicture(file, executor,
object : ImageCapture.OnImageSavedListener {
override fun onError(
error: ImageCapture.ImageCaptureError,
message: String, exc: Throwable?) {
val msg = "Photo capture failed: $message"
Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
Log.e("CameraXApp", msg)
exc?.printStackTrace()
}
override fun onImageSaved(file: File) {
val msg = "Photo capture succeeded: ${file.absolutePath}"
Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
Log.d("CameraXApp", msg)
}
})
CameraX.bindToLifecycle(this, preview, imageCapture)
Extensions
CameraX提供了一种API,以实现可选效果,例如HDR,人像以及制造商为特定手机实现的其他效果。为了使设备支持供应商扩展,必须满足以下所有条件:
- 效果具有设备OEM的库支持。
- OEM库已安装在当前设备上。
- OEM库将设备报告为支持扩展。
- 该设备具有该库所需的操作系统版本。
要将供应商扩展应用于CameraX用例,请创建一个Extender
对象,该对象可让您Builder
使用该效果或功能的设置进行配置。向该分机查询可用性,因为如果分机不可用,则该enableExtension()
呼叫将不执行任何操作。
import androidx.camera.extensions.BokehExtender
fun onCreate() {
// Create a Builder same as in normal workflow.
val builder = ImageCaptureConfig.Builder()
// Create a Extender object which can be used to apply extension
// configurations.
val bokehImageCapture = BokehImageCaptureExtender.create(builder)
// Query if extension is available (optional).
if (bokehImageCapture.isExtensionAvailable()) {
// Enable the extension if available.
bokehImageCapture.enableExtension()
}
// Finish constructing configuration with the same flow as when not using
// extensions.
val config = builder.build()
val useCase = ImageCapture(config)
CameraX.bindToLifecycle(this as LifecycleOwner, useCase)
}
要禁用供应商扩展,我们必须创建新的图像捕获用例实例。
camerax extensions.kt
翻译自:https://proandroiddev.com/exploring-the-new-camerax-library-in-android-ed10e64a5b3b