我正在尝试将相机项目更新为Android N,因此将旧的CameraCaptureSession移至ReprocessableCaptureSession.我做到了,它工作正常,但是有了这个新功能,我可以在我的相机中使用CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG模板设备,我可以使用reprocessCaptureRequest重新处理框架.

这是我的问题出现的地方.因为我找不到任何示例,并且我不太了解有关如何使用reprocessCaptureRequest的小文档:

Each reprocess CaptureRequest processes one buffer from CameraCaptureSession’s input Surface to all output Surfaces included in the reprocess capture request. The reprocess input images must be generated from one or multiple output images captured from the same camera device. The application can provide input images to camera device via queueInputImage(Image). The application must use the capture result of one of those output images to create a reprocess capture request so that the camera device can use the information to achieve optimal reprocess image quality. For camera devices that support only 1 output Surface, submitting a reprocess CaptureRequest with multiple output targets will result in a CaptureFailure.

我尝试查看有关google.sources年相机的CTS测试,但它们的功能与我相同.使用多个imageReader,将图片的TotalCaptureResult保存在LinkedBlockingQueue< TotalCaptureResult>中.然后再调用:

TotalCaptureResult totalCaptureResult = state.captureCallback.getTotalCaptureResult();

CaptureRequest.Builder reprocessCaptureRequest = cameraStore.state().cameraDevice.createReprocessCaptureRequest(totalCaptureResult);

reprocessCaptureRequest.addTarget(state.yuvImageReader.getSurface());

sessionStore.state().session.capture(reprocessCaptureRequest.build(), null, this.handlers.bg());

但这总是抛出RuntimeException:

java.lang.RuntimeException:捕获失败:原因170帧中为0,

我只想知道哪种是与ReprocessableCaptureSession一起使用的正确方法,因为我已经尝试了所有方法,而且我不知道自己在做什么错.

解决方法:

最后,我找到了使我的reprocessableCaptureSession工作的解决方案.

我使用Flux体系结构,因此当您看到Dispatcher.dispatch(action)时不要感到困惑,只需将其视为回调即可.所以,这是我的代码:

首先,如何创建会话:

//Configure preview surface

Size previewSize = previewState.previewSize;

previewState.previewTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());

ArrayList targets = new ArrayList<>();

for (SessionOutputTarget outputTarget : state.outputTargets) {

Surface surface = outputTarget.getSurface();

if (surface != null) targets.add(surface);

}

targets.add(previewState.previewSurface);

CameraCharacteristics cameraCharacteristics = cameraStore.state().availableCameras.get(cameraStore.state().selectedCamera);

Size size = CameraCharacteristicsUtil.getYuvOutputSizes(cameraCharacteristics).get(0);

InputConfiguration inputConfiguration = new InputConfiguration(size.getWidth(),

size.getHeight(), ImageFormat.YUV_420_888);

CameraCaptureSession.StateCallback sessionStateCallback = new CameraCaptureSession.StateCallback() {

@Override

public void onConfigured(@NonNull CameraCaptureSession session) {

if (sessionId != currentSessionId) {

Timber.e("Session opened for an old open request, skipping. Current %d, Request %d", currentSessionId, sessionId);

//performClose(session);

return;

}

try {

session.getInputSurface();

//This call is irrelevant,

//however session might have closed and this will throw an IllegalStateException.

//This happens if another camera app (or this one in another PID) takes control

//of the camera while its opening

} catch (IllegalStateException e) {

Timber.e("Another process took control of the camera while creating the session, aborting!");

}

Dispatcher.dispatchOnUi(new SessionOpenedAction(session));

}

@Override

public void onConfigureFailed(@NonNull CameraCaptureSession session) {

if (sessionId != currentSessionId) {

Timber.e("Configure failed for an old open request, skipping. Current %d, request %d", currentSessionId, sessionId);

return;

}

Timber.e("Failed to configure the session");

Dispatcher.dispatchOnUi(new SessionFailedAction(session, new IllegalStateException("onConfigureFailed")));

}

};

if (state.outputMode == OutputMode.PHOTO) {

cameraState.cameraDevice.createReprocessableCaptureSession(inputConfiguration, targets, sessionStateCallback, handlers.bg());

} else if (state.outputMode == OutputMode.VIDEO) {

cameraState.cameraDevice.createCaptureSession(targets, sessionStateCallback, handlers.bg());

}

} catch (IllegalStateException | IllegalArgumentException e) {

Timber.e(e, "Something went wrong trying to start the session");

} catch (CameraAccessException e) {

//Camera will throw CameraAccessException if another we try to open / close the

//session very fast.

Timber.e("Failed to access camera, it was closed");

}

使用4个表面(预览,YUV(输入),JPEG和RAW)创建的照片会话.之后,我配置了imageWriter:

Dispatcher.subscribe(Dispatcher.VERY_HIGH_PRIORITY, SessionOpenedAction.class)

.filter(a -> isInPhotoMode())

.subscribe(action -> {

PhotoState newState = new PhotoState(state());

newState.zslImageWriter = ImageWriter.newInstance(action.session.getInputSurface(), MAX_REPROCESS_IMAGES);

setState(newState);

});

好的,现在我们已经创建了ImageWriter和会话.不,我们从重复请求开始流式传输:

CaptureRequest.Builder captureRequestBuilder =

cameraStore.state().cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG);

captureRequestBuilder.addTarget(previewStore.state().previewSurface);

captureRequestBuilder.addTarget(photoStore.state().yuvImageReader.getSurface());

state.session.setRepeatingRequest(captureRequestBuilder.build(), state.zslCaptureCallback, handlers.bg());

要添加大量代码,只需说zslCaptureCallback是自定义回调,它保存在LinkedBlockingQueue< TotalCaptureRequest>中. X个最后的TotalCaptureRequests.另外,我对yuvImageReader(输入一个)进行了同样的操作,将最后的X个图像保存在队列中.

最后是我的“拍照”方法:

try {

//Retrieve the last image stored by the zslImageReader

Image image = zslImageReaderListener.getImage();

//Retrieve the last totalCaptureResult from the zslCaptureCallback and create a reprocessableCaptureRequest with it

TotalCaptureResult captureResult = sessionStore.state().zslCaptureCallback.getCaptureResult(image.getTimestamp());

CaptureRequest.Builder captureRequest = cameraStore.state().cameraDevice.createReprocessCaptureRequest(captureResult);

//Add the desired target and values to the captureRequest

captureRequest.addTarget(state().jpegImageReader.getSurface());

//Queued back to ImageWriter for future consumption.

state.zslImageWriter.queueInputImage(image);

//Drain all the unused and queued CapturedResult from the CaptureCallback

sessionStore.state().zslCaptureCallback.drain();

//Capture the desired frame

CaptureRequest futureCaptureResult = captureRequest.build();

sessionStore.state().session.capture(futureCaptureResult, new CameraCaptureSession.CaptureCallback() {

@Override

public void onCaptureCompleted(@NonNull CameraCaptureSession session,

@NonNull CaptureRequest request,

@NonNull TotalCaptureResult result) {

Dispatcher.dispatchOnUi(new PhotoStatusChangedAction(PhotoState.Status.SUCCESS));

}

@Override

public void onCaptureFailed(@NonNull CameraCaptureSession session,

@NonNull CaptureRequest request,

@NonNull CaptureFailure failure) {

super.onCaptureFailed(session, request, failure);

Exception captureFailedException = new RuntimeException(

String.format("Capture failed: Reason %s in frame %d, was image captured? -> %s",

failure.getReason(),

failure.getFrameNumber(),

failure.wasImageCaptured()));

Timber.e(captureFailedException, "Cannot take mediaType, capture failed!");

Dispatcher.dispatchOnUi(new PhotoStatusChangedAction(PhotoState.Status.ERROR, captureFailedException));

}

}, this.handlers.bg());

//Capture did not blow up, we are taking the photo now.

newState.status = PhotoState.Status.TAKING;

} catch (CameraAccessException | InterruptedException| IllegalStateException | IllegalArgumentException | SecurityException e) {

Timber.e(e, "Cannot take picture, capture error!");

newState.status = PhotoState.Status.ERROR;

}

标签:android-camera2,image,camera,java,android

来源: https://codeday.me/bug/20191112/2023478.html

java processrequest_java-如何在camera2 API中使用reprocessCaptureRequest相关推荐

  1. eclipse java luna,java-如何在Eclipse Luna中配置Lombok

    java-如何在Eclipse Luna中配置Lombok 我使用Maven在Eclipse Luna中配置了龙目岛. 注释已正确添加,但没有生成getter和setter. eclipse.ini ...

  2. 在java中添加源_关于Java:如何在Android Studio中添加链接的源文件夹?

    在Eclipse中,我可以将源文件夹作为"链接的源文件夹"添加到我的android项目中. 如何在Android Studio中实现同一目的? 或者是否可以添加外部文件夹以构建gr ...

  3. react 生命挂钩_如何在GraphQL API中使用React挂钩来管理状态

    react 生命挂钩 In this blog post, we are going to learn - 在这篇博客中,我们将学习- What React hooks are什么是React钩子 H ...

  4. 如何在web api中使用SignalR

    说明: 在webapi中使用signalr,使用IIS 环境: vs2012, .net4.5 第一步:建web api项目 第二步:nuget导入signalr Install-Package Mi ...

  5. 如何在REST API中使用查阅项的值作为过滤条件

    原文地址:点击打开链接 这是要解决的问题:在使用REST API的时候,对于lookup类型的列,不能使用它的值来过滤item. 原因其实很简单,使用REST API获取的值是id,而不是我们想得到的 ...

  6. java jpa 配置文件_关于java:如何在JPA配置中设置默认模式名称?

    我发现在hibernate配置文件中我们可以设置参数hibernate.default_schema: ... myschema ... 现在我正在使用JPA,我也希望这样做. 否则我必须为每个@Ta ...

  7. JAVA:如何在Windows7系统中配置环境变量。

    笔者之前因为操作系统老旧而在网络上苦苦搜寻不到环境变量配置的方法,最终在<Java:从入门到精通>的旧版书上找到了解决办法,故将其抄录下来分享给大家. 在Windows 7系统中配置环境变 ...

  8. info java module_如何在Jdk9 / java-9中解决module-info.java编译错误

    我试图使用jdk-9在代码下运行,但在使用命令编译时遇到问题 命令 javac -d mods .\module-info.java com\nirav\modi\Test.java 错误 .\mod ...

  9. java smack_java – 如何在Android smack中正确接受好友请求?

    有一个openfire服务器和 Android客户端(smack).所有客户端都可以互相添加到好友/名单列表中(未经授权,我希望用户可以在没有接受好友请求的情况下看到对方).我在获取好友请求发件人的状 ...

最新文章

  1. JS计算起点坐标到终点坐标的驾车距离和驾车时间
  2. 3位物理学家获基础物理学特别突破奖
  3. 什么原因导致芯片短路_常见的芯片故障现象
  4. python入门经典例题-Python入门_列表练习题
  5. STM32 基础系列教程 40 - Lwip_mqtt
  6. 【PAT】A1074 Reversing Linked List ***
  7. Keyboard驱动介绍
  8. Mysql解决死锁的问题,防止阻塞
  9. 10个最棒的jQuery视频插件
  10. 此版本的visual studio无法打开下列项目_深度学习实现高精度钢琴曲转谱Piano transcription项目简明使用教程...
  11. 1992-2018年中国各地级市夜间灯光数据
  12. 原创:艰难的PCS7安装过程
  13. 对计算机的一点点看法
  14. 安卓抓jdwskey
  15. 宋楚老师银行风险与合规讲师
  16. STM32 SWD 只能下载一次的问题
  17. 电大计算机形考试题,电大计算机形考试题1.doc
  18. 1014长短期记忆网络(LSTM)
  19. 误发邮件如何能撤回?
  20. 官网电子安全证书端口即将到期!新型诈骗短信!

热门文章

  1. 修饰性形容词-big、good、high_35
  2. java加载图片白屏,tomcat白屏~
  3. c语言 python java_C语言、C++、Java,Python之间的区别,哪个更有前景,哪个更难 ?...
  4. 缓慢的http拒绝服务攻击 tomcat_攻击技术
  5. 【英语学习】【WOTD】farouche 释义/词源/示例
  6. php连接db2失败,PHP_浅谈DB2数据库故障处理及最佳实践,  当你在使用数据库时,可 - phpStudy...
  7. MFC获取文件夹下的所有文件名
  8. python fortran混合编程输入矩阵_如何将动态数组从Python传递到Fortran动态链接库
  9. python 什么是序列_从零起步学Python——什么是序列?
  10. linux0.11内核视频讲解,linux0.11内核分析-setup