本文介绍了使用摄像机2 API,而preVIEW拍摄照片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要实现的是捕获的画面没有显示preVIEW,直接发送输出到的ImageReader 什么。
我已经使用了 Camera2Basic 的例子作为一个起点。
但是,回调我的的ImageReader 永远不会被调用,因此没有图像发送到它的表面
我真的需要先显示一个preVIEW?

这是相机code,这是下令异步回调的流动如下:

私人的ImageReader的ImageReader;
私人处理器backgroundHandler;
私人HandlerThread backgroundThread;
私人字符串cameraId;
私人CameraDevice cameraDevice;
私人CameraCaptureSession cameraCaptureSession;

  @覆盖
公共无效的onCreate(){
    setupCamera2();
}私人无效setupCamera2(){
    CameraManager经理=(CameraManager)getSystemService(Context.CAMERA_SERVICE);    尝试{        为(字符串cameraId:manager.getCameraIdList()){
        CameraCharacteristics特性= manager.getCameraCharacteristics(c​​ameraId);        如果(characteristics.get(CameraCharacteristics.LENS_FACING)!= CameraCharacteristics.LENS_FACING_FRONT){
            继续;
        }        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);
        }    }赶上(CameraAccessException | NullPointerException异常五){
        e.printStackTrace();
    }
}
私人无效openCamera2(){
    CameraManager经理=(CameraManager)getSystemService(Context.CAMERA_SERVICE);
    尝试{        manager.openCamera(cameraId,cameraStateCallback,backgroundHandler);    }赶上(CameraAccessException E){
        e.printStackTrace();
    }
}私人最终CameraDevice.StateCallback cameraStateCallback =新CameraDevice.StateCallback(){
    @覆盖
    公共无效onOpened(CameraDevice设备){
        cameraDevice =设备;
        createCameraCaptureSession();
    }    @覆盖
    公共无效onDisconnected(CameraDevice cameraDevice){}    @覆盖
    公共无效onerror的(CameraDevice cameraDevice,INT ERROR){}
};私人无效createCaptureSession(){
    清单<表面> outputSurfaces =新的LinkedList<>();
    outputSurfaces.add(imageReader.getSurface());    尝试{        cameraDevice.createCaptureSession(outputSurfaces,新CameraCaptureSession.StateCallback(){
            @覆盖
            公共无效onConfigured(CameraCaptureSession会话){
                cameraCaptureSession =会议;
            }            @覆盖
            公共无效onConfigureFailed(CameraCaptureSession会话){}
        }, 空值);    }赶上(CameraAccessException E){
        e.printStackTrace();
    }
}
私人最终ImageReader.OnImageAvailableListener onImageAvailableListener =新ImageReader.OnImageAvailableListener(){
    @覆盖
    公共无效onImageAvailable(ImageReader的读者){
        createCaptureRequest();
    }
};
私人无效createCaptureRequest(){
    尝试{        CaptureRequest.Builder requestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
        requestBuilder.addTarget(imageReader.getSurface());        //焦点
        requestBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);        //方向
        INT旋转= windowManager.getDefaultDisplay()getRotation()。
        requestBuilder.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATIONS.get(旋转));        cameraCaptureSession.capture(requestBuilder.build(),camera2Callback,NULL);    }赶上(CameraAccessException E){
        e.printStackTrace();
    }
}


解决方案

您应该捕捉onConfigured的照片的功能,但不onImageAvailable。

 公共无效onConfigured(CameraCaptureSession会话){
            cameraCaptureSession =会议;
            createCaptureRequest();
        }

在此功能onImageAvailable,你应该保存图像,

 形象画像= mImageReader.acquireLatestImage();
ByteBuffer的缓冲液= image.getPlanes()[0] .getBuffer();
字节[]字节=新字节[buffer.remaining()];
buffer.get(字节);
尝试{
    保存(字节,文件);
}赶上(IOException异常五){
    e.printStackTrace();
}
image.close();

onImageAvailable功能将session.capture后调用()。

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;

@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();
    }
}
解决方案

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

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

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" function will be invoked after session.capture() .

这篇关于使用摄像机2 API,而preVIEW拍摄照片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-18 13:33