Gio*_*bar 5 android kotlin android-camerax
我仍在练习 Kotlin 和 Android 开发。据我了解,Camera 类已被弃用,Android 邀请使用 Camerax 来代替,因为这个高级类是独立于设备的,并且它们简化了在应用程序上实现相机的过程。
我尝试阅读文档(https://developer.android.com/training/camerax),但它写得太糟糕了,我几乎不明白他们试图解释的内容。所以我去阅读了文档本身给出的整个示例代码(https://github.com/android/camera-samples/tree/main/CameraXBasic)。CameraFragment 代码大约有 500 行长(忽略导入和各种注释)。
我真的需要编写 500 行代码来简单地拍照吗?这怎么能被认为是“比以前简单”呢?
我的意思是,在 Android 编程中,我只需要编写 4 行代码即可要求用户从其存储中选择一个图像并检索它并将其显示在 ImageView 中。有没有一种真正简单的拍照方法,或者我真的需要停下来并失去一整天的工作来编写所有这些代码行?
编辑:获取文档的此页面: https://developer.android.com/training/camerax/architecture#kotlin 它以这段代码开始。
val preview = Preview.Builder().build()
val viewFinder: PreviewView = findViewById(R.id.previewView)
// The use case is bound to an Android Lifecycle with the following code
val camera = cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview)
Run Code Online (Sandbox Code Playgroud)
CameraProvider 不知从何而来。这应该是什么?我发现它是一个 ProcessCameraProvider,但是我应该如何初始化它?它应该是一个 Lateinit var 还是已经在其他地方初始化了?因为如果我尝试写入,val cameraProvider = ProcessCameraProvider()就会出现错误,那么我该怎么办?什么是cameraSelector参数?之前没有定义过。我发现它是前置摄像头或后置摄像头的选择器,但是阅读该文档的那一页我怎么知道它呢?这份文档怎么可能在发布时存在这些缺陷呢?怎样才能让一个人轻松学习呢?
Hus*_*eem 17
在使用 CameraX 与设备的摄像头交互之前,您需要初始化该库。初始化过程是异步的,涉及加载有关设备摄像头的信息等操作。
您可以使用ProcessCameraProvider. 它是一个单例,因此第一次获得 if 的实例时,CameraX 会执行其初始化。
val cameraProviderFuture: ListenableFuture<ProcessCameraProvider> = ProcessCameraProvider.getInstance(context)
Run Code Online (Sandbox Code Playgroud)
获取ProcessCameraProvider单例会返回 a,Future因为它可能需要异步初始化库。第一次获取它时,可能需要一些时间(通常不到一秒),但后续调用将立即返回,因为初始化已经执行。
用手拿着ProcessCameraProvider,您就可以开始与设备的摄像头进行交互。您可以使用 来选择要与哪个相机进行交互CameraSelector,它包含了一组您要使用的相机的滤镜。通常,如果您只是尝试使用主后置或前置摄像头,则可以使用CameraSelector.DEFAULT_BACK_CAMERA或CameraSelector.DEFAULT_FRONT_CAMERA。
现在您已经定义了要使用的相机,接下来可以构建所需的用例。例如,您想要拍照,因此您将使用ImageCapture用例。它允许使用相机拍摄单个捕获帧(通常是高质量的帧),并将其作为原始缓冲区提供,或将其存储在文件中。要使用它,您可以根据需要对其进行配置,也可以让 CameraX 使用默认配置。
val imageCapture = ImageCapture.Builder().build()
Run Code Online (Sandbox Code Playgroud)
在 CameraX 中,相机的生命周期由 控制LifecycleOwner,这意味着当 的LifecycleOwner生命周期开始时,相机打开,当它停止时,相机关闭。因此,您需要选择一个可以控制相机的生命周期。如果您使用的是Activity,您通常希望相机在Activity启动时启动,并在停止时停止,因此您可以使用Activity实例本身作为LifecycleOwner,如果您使用的是Fragment,您可能希望使用其视图生命周期 (Fragment.getViewLifecycleOwner())。
最后,您需要将拼图的各个部分拼凑在一起。
processCameraProvider.bindToLifecycle(
lifecycleOwner,
cameraSelector,
imageCapture
)
Run Code Online (Sandbox Code Playgroud)
应用程序通常包含一个显示相机预览的取景器,因此您可以使用Preview用例,并将其与用例绑定ImageCapture。该Preview用例允许将相机帧流式传输到Surface. 由于设置Surface并在其上正确绘制预览可能很复杂,CameraX 提供了PreviewView,View可与用例一起使用Preview来显示相机预览。您可以在此处查看如何使用它们。
// Just like ImageCapture, you can configure the Preview use case if you'd wish.
val preview = Preview.Builder().build()
// Provide PreviewView's Surface to CameraX. The preview will be drawn on it.
val previewView: PreviewView = findViewById(...)
preview.setSurfaceProvider(previewView.surfaceProvider)
// Bind both the Preview and ImageCapture use cases
processCameraProvider.bindToLifecycle(
lifecycleOwner,
cameraSelector,
imageCapture,
preview
)
Run Code Online (Sandbox Code Playgroud)
现在要实际拍照,您可以使用 ofImageCapture的takePicture方法。一个提供捕获图像的 JPEG 原始缓冲区,另一个将其保存在您提供的文件中(如果需要,请确保您具有必要的存储权限)。
imageCapture.takePicture(
ContextCompat.getMainExecutor(context), // Defines where the callbacks are run
object : ImageCapture.OnImageCapturedCallback() {
override fun onCaptureSuccess(imageProxy: ImageProxy) {
val image: Image = imageProxy.image // Do what you want with the image
imageProxy.close() // Make sure to close the image
}
override fun onError(exception: ImageCaptureException) {
// Handle exception
}
}
)
Run Code Online (Sandbox Code Playgroud)
val imageFile = File("somePath/someName.jpg") // You can store the image in the cache for example using `cacheDir.absolutePath` as a path.
val outputFileOptions = ImageCapture.OutputFileOptions
.Builder(imageFile)
.build()
takePicture(
outputFileOptions,
CameraXExecutors.mainThreadExecutor(),
object : ImageCapture.OnImageSavedCallback {
override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
}
override fun onError(exception: ImageCaptureException) {
}
}
)
Run Code Online (Sandbox Code Playgroud)
我真的需要编写 500 行代码来简单地拍照吗?这怎么能被认为是“比以前简单”呢?
CameraXBasic 并不像其名称所暗示的那样“基本” x) 它更多的是 CameraX 3 个用例的完整示例。尽管CameraFragment很长,但它解释得很好,因此每个人都更容易理解。
CameraX“比以前更简单”,之前主要指的是 Camera2,至少入门起来更具挑战性。CameraX 以其使用用例的方法提供了对开发人员更加友好的 API。它还处理兼容性,这以前是一个大问题。确保您的相机应用程序在大多数 Android 设备上可靠运行非常具有挑战性。
| 归档时间: |
|
| 查看次数: |
9655 次 |
| 最近记录: |