图像捕获和多像素数据提取-android studio上的Kotlin / Java编程替代方案

时间:2019-12-04 17:14:41

标签: android-camera2 android-camerax

我正在使用与 ImageCapture 用例相关联的 ImageCapture.OnImageCapturedListener.onCaptureSuccess 提供的 ImageProxy 实例。该实例是在与按钮相关联的回调中创建的,以触发捕获。 上下文有点棘手,需要了解CameraX API才能完全理解它。

我的问题与摄影机回调而非CameraX API提供的ImageProxy的使用有关

onCaptureSuccess的原型如下: onCaptureSuccess(imageProxy:ImageProxy ?, angle_deg:Int),其中 imageProxy 是图像框架容器, angle_deg 相机旋转的值。

根据图像使用者的不同,有多种选择可以使图像执行逐像素处理。 其中之一是创建 Bitmap ,但是 BitmapFactory 创建者和 Bitmap 创建函数都无法提供直接的解决方案。

在我的上下文中,我使用了图像将其保存到文件中(为此,我需要创建一个文件,其中图像数据将从位图中流出来。 >)和同一张图片进行图片分类(为此,我需要创建一个张量-PyTorch InputTensor -使用临时的位图)。

我定义了Kotlin从ImageProxy转换为File或Bitmap的转换功能。 在以下代码示例中,输入ImageProxy是调用对象this

通过作用域函数.let.apply,输入对象被转换为级联的中间上下文对象,其级联深度足以能够调用buffer.get(data)的像素数据。 从托管ImageProxy中提取数据后,就可以“后退”以返回预期的对象(FileBitmap)。 出于无法解释的原因,当多次使用ImageProxy时,有必要“倒带”调用buffer.rewind()的内部缓冲区。

要文件的ImageProxy

要从File创建ImageProxy,必须从ByteBufferbuffer)中提取数据并保存到ByteArray({{1 }})通过data(例如ByteArrayOutputStream)流到文件中。

out

ImageProxy到位图

要从 fun ImageProxy.toFile(): File { return File(parentActivity.getExternalFilesDir(Environment.DIRECTORY_PICTURES),"${System.currentTimeMillis()}.jpg").apply{ FileOutputStream(this.path).use { stream -> getPlanes()[0].buffer.let{ buffer -> buffer.rewind() // <---- it makes it work ByteArray(buffer.capacity()).let { data -> buffer.get(data) BitmapFactory.decodeByteArray(data, 0, data.size).apply{ compress(Bitmap.CompressFormat.JPEG,100, stream) } } } } } 创建Bitmap,必须从ImageProxyByteBuffer)中提取数据并保存到buffer({{1 }}),它用于使用因子类ByteArray创建位图。

data

如果两个转换函数在同一个ImageProxy实例上一个接一个地调用

BitmapFactory

如果代码中省略了 fun ImageProxy.toBitmap(): Bitmap { getPlanes()[0].buffer.let { buffer -> buffer.rewind() // <---- it makes it work ByteArray(buffer.capacity()).let { data -> buffer.get(data) return BitmapFactory.decodeByteArray(data, 0, data.size) } } } ,则第二个失败。

查看堆栈跟踪及其在何处被撞掉,这是因为缓冲区长度大于 ByteBuffer 类({{隐含的那个)中的其余数据( fun onCaptureSuccess(imageProxy: ImageProxy?, angle_deg: Int) { File saved=imageProxy.toFile() Bitmap bitmap=imageProxy.toBitmap() } ) 1}})。

似乎图像代理的状态取决于之前执行的操作。我找不到一些重置状态函数来处理。

问题

得到的代码有些复杂,仅获得一堆像素。有没有其他更简单的方法可以做到这一点而又不影响ImageProxy的内部状态(某些带有某些缓冲区的像素平面的像素)?

还有其他编程替代方法(通过NDK或JNI或自定义的开放CV代码)处理图像像素吗?

0 个答案:

没有答案