问题描述
我要实现的是捕获的画面没有显示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(cameraId); 如果(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拍摄照片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!