安卓相机2基础API

5
我正在阅读有关Android Camera2 APIs的代码,它来自这里: https://github.com/googlesamples/android-Camera2Basic 但是在以下行中很混乱: https://github.com/googlesamples/android-Camera2Basic/blob/master/Application/src/main/java/com/example/android/camera2basic/Camera2BasicFragment.java#L570-L574 仅将TextureView作为目标添加到previewRequest builder中。 但是下一行实际上将两者都添加为目标。 据我理解,在预览期间,这不应该触发"OnImageAvailable"监听器,对吗? 那么为什么要在此处添加imagereader的surface呢?
我试图在此处删除imagereader的surface,但是当我真正想要捕获图像时,却出现了错误.....
非常困惑!!!

ImageReader 用于获取捕获的图像数据并保存到文件中。在使用 CaptureRequest.Builder 捕获图像之前,必须将 ImageReader 的表面添加到 CaptureSession 中,参考文档 - calvinfly
1个回答

10
在创建CameraCaptureSession时,您需要声明所有可能接收图像数据的输出Surface。这是框架的设计方式。
每当您创建CaptureRequest时,都会添加一个(列表)目标输出Surface。这是捕获帧的图像数据将要传输到的位置-它可以是与TextureView相关联的Surface,用于显示,也可以与ImageReader相关联,用于保存,或与Allocation相关联,用于处理等。(Surface实际上只是一个缓冲区,可以接收摄像头输出的数据。该缓冲区关联的对象类型决定了您如何访问/处理数据。)
您不必将每个帧的数据发送到所有已注册的Surface,但必须发送到其子集。如果在创建时未向CameraCaptureSession注册Surface,则无法将其作为目标添加到CaptureRequest中。尽管可以这样做,但将其传递给会话将导致崩溃,因此请勿这样做。

嗨,萨姆纳,感谢您的解释。在我看来,有两个不同的捕获会话,一个用于预览,另一个用于实际捕获。我感到困惑,因为我只应该将图像读取器的表面注册到实际捕获会话中,对吧? - Coderzelf
CameraCaptureSessions非常大且昂贵,很少被创建。通常,您会决定要将哪些输出表面发送到不同的目的地(显示、保存等),然后创建一个单独的Session,并将每个表面都注册到其中,以便您可以通过向该部分发出CaptureRequests来随时使用它们。您应该注意到,在camera2basic中,他们只创建了一个CameraCaptureSession。 - rcsumner
一个CameraCaptureSession就像整个相机管道的配置,与其注册的Surfaces是输出管道-硬连到被创建的基础设施中。你不想建立多个基础设施,只需为多个输出设置一个即可。 - rcsumner
@Sumber 谢谢!我对使用Allocation来存储图像缓冲区很感兴趣,我做了一些搜索,但似乎有些困惑。你能给我一个示例的指针,让我正确地使用Allocation吗?(还有可能告诉我如何从中获取位图吗?)谢谢!!! - Coderzelf
我通常只使用显示输出和ImageReaders将各种格式保存到磁盘,以便在其他环境中处理它们,因此我不熟悉使用Allocations和RenderScript对位图进行设备端图像处理...抱歉!但是,肯定有涉及该方面的教程! - rcsumner
这里的HDR取景器演示:https://github.com/googlesamples/android-HdrViewfinder 使用一个Allocation作为相机输出。Allocation只需要是正确类型(YUV)和正确标志(IO_INPUT)。ViewfinderProcessor.java文件具有RenderScript设置和调用代码:https://github.com/googlesamples/android-HdrViewfinder/blob/master/Application/src/main/java/com/example/android/hdrviewfinder/ViewfinderProcessor.java - Eddy Talvala

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接