使用camera2 API捕获无预览的图片 [英] Capture picture without preview using camera2 API

查看:1355
本文介绍了使用camera2 API捕获无预览的图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要实现的是捕获图片而不显示预览,直接将输出发送到 ImageReader
我使用了 Camera2Basic示例作为起点。
然而,我的 ImageReader 的回调从未被调用,因此没有图像发送到它的 Surface
我真的需要先显示预览吗?

What I want to achieve is capturing a picture without showing the preview, sending directly the output to an ImageReader. I have used the Camera2Basic example as a starting point. However, the callback of my ImageReader is never called, hence no image is sent to its Surface. Do I really need to display a preview first?

这是相机代码,按照异步回调的流程排序:

This is the camera code, which is ordered following the flow of the asynchronous callbacks:

private ImageReader imageReader;
private Handler backgroundHandler;
private HandlerThread backgroundThread;
private String cameraId;
private CameraDevice cameraDevice;
private CameraCaptureSession cameraCaptureSession;

private ImageReader imageReader; private Handler backgroundHandler; private HandlerThread backgroundThread; private String cameraId; private CameraDevice cameraDevice; private CameraCaptureSession cameraCaptureSession;

@Override
public void onCreate() {
    setupCamera2();
}

private void setupCamera2() {
    CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);

    try {

        for (String cameraId : manager.getCameraIdList()) {
        CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);

        if (characteristics.get(CameraCharacteristics.LENS_FACING) != CameraCharacteristics.LENS_FACING_FRONT) {
            continue;
        }

        this.cameraId = cameraId;

        int[] picSize = Settings.getPictureSize();
        int picWidth = picSize[0];
        int picHeight = picSize[1];

        imageReader = ImageReader.newInstance(picWidth, picHeight, ImageFormat.JPEG, 2);
        imageReader.setOnImageAvailableListener(onImageAvailableListener, backgroundHandler);
        }

    } catch (CameraAccessException | NullPointerException e) {
        e.printStackTrace();
    }
}


private void openCamera2() {
    CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    try {

        manager.openCamera(cameraId, cameraStateCallback, backgroundHandler);

    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}



private final CameraDevice.StateCallback cameraStateCallback = new CameraDevice.StateCallback() {
    @Override
    public void onOpened(CameraDevice device) {
        cameraDevice = device;
        createCameraCaptureSession();
    }

    @Override
    public void onDisconnected(CameraDevice cameraDevice) {}

    @Override
    public void onError(CameraDevice cameraDevice, int error) {}
};



private void createCaptureSession() {
    List<Surface> outputSurfaces = new LinkedList<>();
    outputSurfaces.add(imageReader.getSurface());

    try {

        cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
            @Override
            public void onConfigured(CameraCaptureSession session) {
                cameraCaptureSession = session;
            }

            @Override
            public void onConfigureFailed(CameraCaptureSession session) {}
        }, null);

    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}


private final ImageReader.OnImageAvailableListener onImageAvailableListener = new ImageReader.OnImageAvailableListener() {
    @Override
    public void onImageAvailable(ImageReader reader) {
        createCaptureRequest();
    }
};


private void createCaptureRequest() {
    try {

        CaptureRequest.Builder requestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
        requestBuilder.addTarget(imageReader.getSurface());

        // Focus
        requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);

        // Orientation
        int rotation = windowManager.getDefaultDisplay().getRotation();
        requestBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));

        cameraCaptureSession.capture(requestBuilder.build(), camera2Callback, null);

    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}


推荐答案

应该在onConfigured函数中捕获照片,而不是在onImageAvailable上捕获照片。

You should capture photos in "onConfigured" function but not onImageAvailable.

public void onConfigured(CameraCaptureSession session) {
            cameraCaptureSession = session;
            createCaptureRequest();
        }

在此函数onImageAvailable,您应该保存图像,

In this function "onImageAvailable",you should save images,

Image image = mImageReader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
try {
    save(bytes, file);
} catch (IOException e) {
    e.printStackTrace();
}
image.close();

onImageAvailable函数将在session.capture()之后被调用。

"onImageAvailable" function will be invoked after session.capture() .

这篇关于使用camera2 API捕获无预览的图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆