如何在Camera2 API Android 5.0中获得单个预览帧?
我正在尝试使用Camera2 API获取二维码扫描功能的预览帧。在旧的摄像头API中,它非常简单:如何在Camera2 API Android 5.0中获得单个预览帧?,android,android-camera,android-5.0-lollipop,android-hardware,Android,Android Camera,Android 5.0 Lollipop,Android Hardware,我正在尝试使用Camera2 API获取二维码扫描功能的预览帧。在旧的摄像头API中,它非常简单: android.hardware.Camera mCamera; ... mCamera.setPreviewCallback(new Camera.PreviewCallback() { @Override public void onPreviewFrame(byte[] data, Camera camera) {
android.hardware.Camera mCamera;
...
mCamera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
// will be invoked for every preview frame in addition to displaying them on the screen
}
});
但是,我无法通过使用新的Camera2 API找到实现这一点的方法。我想接收多个可以处理的帧——最好是像旧API一样接收字节数组。有什么办法吗?请使用下面的代码
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
try {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraDevice.getId());
Size[] jpegSizes = null;
if (characteristics != null) {
jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.JPEG);
}
int width = 480;//480x320
int height = 320;
if (jpegSizes != null && 0 < jpegSizes.length) {
width = jpegSizes[0].getWidth();
height = jpegSizes[0].getHeight();
}
ImageReader reader = ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
List<Surface> outputSurfaces = new ArrayList<Surface>(2);
outputSurfaces.add(reader.getSurface());
outputSurfaces.add(new Surface(textureView.getSurfaceTexture()));
final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(reader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
// Orientation
int rotation = ((Activity) context).getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
final File file = getFileDir();
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
try {
image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
save(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (image != null) {
image.close();
}
}
}
private void save(byte[] bytes) throws IOException {
OutputStream output = null;
try {
output = new FileOutputStream(file);
output.write(bytes);
} finally {
if (null != output) {
output.close();
}
}
}
};
reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
CameraManager=(CameraManager)context.getSystemService(context.CAMERA_服务);
试一试{
CameraCharacteristics characteristics=manager.getCameraCharacteristics(cameraDevice.getId());
Size[]jpegsize=null;
如果(特征!=null){
jpegSizes=characteristics.get(CameraCharacteristics.SCALER\u STREAM\u CONFIGURATION\u MAP).getOutputSizes(ImageFormat.JPEG);
}
int width=480;//480x320
内部高度=320;
if(jpegSizes!=null&&0
有点晚了,但总比没有好:
通常使用TextureView
来显示相机的预览。您可以使用TextureView.SurfacetTextureListener
在每次曲面更改时获取回调TextureView
提供了一种方法getBitmap(Bitmap)
,您可以使用该方法获得与TextureView
相同大小的预览帧
你可以用它作为起点。只需更新SurfaceTextRelister,如下所示:
private val surfaceTextureListener = object : TextureView.SurfaceTextureListener {
override fun onSurfaceTextureAvailable(texture: SurfaceTexture, width: Int, height: Int) {
openCamera(width, height)
}
override fun onSurfaceTextureSizeChanged(texture: SurfaceTexture, width: Int, height: Int) {
configureTransform(width, height)
}
override fun onSurfaceTextureDestroyed(texture: SurfaceTexture) = true
override fun onSurfaceTextureUpdated(texture: SurfaceTexture) {
// Start changes
// Get the bitmap
val frame = Bitmap.createBitmap(textureView.width, textureView.height, Bitmap.Config.ARGB_8888)
textureView.getBitmap(frame)
// Do whatever you like with the frame
frameProcessor?.processFrame(frame)
// End changes
}
}
看看这个问题。我发布了这个例子,它使用最新的android2摄像头API来读取二维码。享受cameraDevice从何而来?您正在演示如何捕获图像,问题是如何在捕获图像之前获取预览帧。例如,将imagereader作为捕获的目标RequestBuilder会降低帧速率难以置信,您知道如何获取吗