我尝试使用Camer2 API从相机获取每个帧用于图像处理,但我得到 FATAL EXCEPTION ,其中说
致命的例外:主要 过程:com.example.avoor.camera2api,PID:2831 java.lang.IllegalStateException:图片已经关闭
我成功打开相机并将其发送到TuxtureView进行预览,但是当涉及 OnImageAvailableListener 时应用程序崩溃。
以下是使用的代码:
protected void createCameraPreview() {
try {
SurfaceTexture texture = textureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(imageDimension.getWidth(), imageDimension.getHeight());
Surface surface = new Surface(texture);
ImageReader reader = ImageReader.newInstance(640, 480, ImageFormat.YUV_420_888, 3);
//reader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(surface);
captureRequestBuilder.addTarget(reader.getSurface());
List<Surface> outputSurfaces = new ArrayList<>();
outputSurfaces.add(reader.getSurface());
outputSurfaces.add(surface);
///////////////////////////////////////////////////////////////////
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
try {
image = reader.acquireLatestImage();
final byte[] bytes;
bytes = convertYUV420888ToNV21(image);
Log.d(TAG,"Height:"+String.valueOf(image.getHeight())+
" Width: "+String.valueOf(image.getWidth()));
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
imageView.setImageBitmap(bitmap);
}
}
});
}
catch (IllegalStateException e) {
Log.e(TAG, "Too many images queued for saving, dropping image for request: ");
return;
}
finally {
if (image != null) {
image.close();
}
}
}
};
reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
///////////////////////////////////////////////////////////////////
cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback(){
@Override
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
//The camera is already closed
if (null == cameraDevice) {
return;
}
// When the session is ready, we start displaying the preview.
cameraCaptureSessions = cameraCaptureSession;
updatePreview();
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
Toast.makeText(MainActivity.this, "Configuration change", Toast.LENGTH_SHORT).show();
}
}, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
在这里:
protected void updatePreview() {
if(null == cameraDevice) {
Log.e(TAG, "updatePreview error, return");
}
captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
try {
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
我在相机打开时启动了 BackgroundThread
答案 0 :(得分:1)
您的读者可能会收集垃圾;你没有把它保存在任何地方,并且它在createCameraPreview结束时超出了范围。
你从中获得了一个Surface,但是Surface就像一个弱引用;它不会使ImageReader无法收集。