![](/img/trans.png)
[英]How to get camera2 preview frames programmatically(without layout) in Android?
[英]Getting android camera2 preview frames without lagging the screen preview
在原始(現已棄用)的相機API中,我們曾經能夠在Camera.PreviewCallback中獲取預覽幀並能夠處理它(可能需要很長時間)並釋放緩沖區以便能夠接收另一幀,而不會滯后屏幕預覽,包含以下代碼:
public void onPreviewFrame(final byte[] data, Camera camera) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
(... do some slow processing ...)
}
@Override
protected void onPostExecute(Void aVoid) {
mCamera.addCallbackBuffer(data); // free the buffer to be able
// to process another frame
}
}.execute();
}
如果有另一個可用於接收它的緩沖區,API將僅使用新幀進行回調,而不會滯后屏幕預覽。
我試圖在新的Camera2 API上復制相同的行為,但我找不到一種方法來做到這一點而不會滯后於屏幕預覽。 如果我向預覽請求添加第二個目標(與屏幕1相同的分辨率,YUV_420_888):
mPreviewRequestBuilder.addTarget(surface);
mPreviewRequestBuilder.addTarget(previewImageReader.getSurface());
mCameraDevice.createCaptureSession(
Arrays.asList(surface, previewImageReader.getSurface()), ...
屏幕預覽會滯后,即使我只是在我得到它時立即關閉圖像:
@Override
public void onImageAvailable(ImageReader reader) {
reader.acquireNextImage().close();
}
使用Camera2模擬原始相機API行為的正確方法是什么(即,只要有一個空閑且沒有減慢屏幕預覽,就會有一個新的緩沖區)?
更新:如果有人想知道代碼的其余部分是什么樣的,它只是標准android-camera2Basic示例的修改版本, 這就是我改變的內容 。
如果有人仍然感興趣。
創建一個SurfaceTextureListener
並從onSurfaceTextureUpdated
方法調用您的異步函數。 在使用BarcodeDetection API和Camera 2 API檢查條形碼的幀時,我已成功使用此功能。
以下是從onSurfaceTextureUpdated
方法啟動的異步函數示例。 如果您只想在后台運行一個異步任務,則可以使用標志來檢查上一個任務是否已完成。
private final TextureView.SurfaceTextureListener mSurfaceTextureListener
= new TextureView.SurfaceTextureListener() {
boolean processing;
@Override
public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
openCamera(width, height);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
configureTransform(width, height);
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture texture) {
if (processing) {
return;
}
processing = true;
Bitmap photo = mTextureView.getBitmap();
new ImageTask(photo, new ImageResponse() {
@Override
public void processFinished() {
processing = false;
}
}).execute();
}
};
private interface ImageResponse {
void processFinished();
}
private class ImageTask extends AsyncTask<Void, Void, Exception> {
private Bitmap photo;
private ImageResponse imageResponse;
ImageTask(Bitmap photo, ImageResponse imageResponse) {
this.photo = photo;
this.imageResponse = imageResponse;
}
@Override
protected Exception doInBackground(Void... params) {
// do background work here
imageResponse.processFinished();
return null;
}
@Override
protected void onPostExecute(Exception result) {
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.