[英]How to get single preview frame in Camera2 API Android 5.0?
I'm trying to get a preview frame for QR code scanning functionality using Camera2 API . 我正在尝试使用Camera2 API获取QR码扫描功能的预览框架 。 In old Camera API it's as easy as: 在旧的Camera API中,它很简单:
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
}
});
However, I can't find a way to achieve that using new Camera2 API. 不过,我不能找到一种方法来实现,使用新的 API Camera2。 I'd like to receive multiple frames that I can work on - the best would be to receive byte array as in old API. 我想收到多个我可以处理的帧 - 最好的是接收旧API中的字节数组。 Any ideas how to do that? 任何想法如何做到这一点?
A little late but better than never: 有点迟,但总比没有好:
Usually a TextureView
is used to display the preview of the camera. 通常, TextureView
用于显示摄像机的预览。 You can use TextureView.SurfaceTextureListener
to get a callback every time the surface changes. 每次曲面更改时,您都可以使用TextureView.SurfaceTextureListener
来获取回调。 TextureView
does provide a method getBitmap(Bitmap)
which you can use to get the preview frame in the same size as the TextureView
. TextureView
确实提供了一个方法getBitmap(Bitmap)
,您可以使用它来获取与TextureView
相同大小的预览框架。
You can use this Google sample as starting point. 您可以使用此Google示例作为起点。 Simply update the surfaceTextureListener like shown here: 只需更新surfaceTextureListener,如下所示:
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
}
}
Use Below code to do so. 使用下面的代码来执行此操作。
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();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.