J'essaye de traiter des cadres avec l'utilisation de ImageReader tout en affichant également l'aperçu de la caméra vidéo sur un SurfaceView. Si la seule surface cible que j'ajoute est SurfaceView, l'aperçu est fluide, mais si j'ajoute un ImageReader comme deuxième cible, l'aperçu commence à être très lent. Pourquoi cela pourrait-il être? J'ai essayé de créer un HandlerThread et un Handler et de les utiliser, mais cela n'a rien changé. La seule chose que je pense actuellement est d'acquérir et de fermer l'image suivante.Camera2API ajoutant ImageReader en tant que surface cible laggs mon aperçu de la caméra
public void startBackgroundThread() {
handlerThread = new HandlerThread("Image Processing Thread");
handlerThread.start();
handler = new Handler(handlerThread.getLooper());
}
Configuration de l'appareil photo ici:
public void configureCamera() {
try {
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
StreamConfigurationMap configs = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] sizes = configs.getOutputSizes(ImageFormat.YUV_420_888);
imageReader = ImageReader.newInstance(sizes[0].getWidth(), sizes[0].getHeight(), ImageFormat.YUV_420_888, 1);
Range<Integer>[] ranges = characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
fpsRange = ranges[ranges.length - 1];
imageReader.setOnImageAvailableListener(this, handler);
cameraSurfaceView.getHolder().setFixedSize(sizes[0].getWidth(), sizes[0].getHeight());
} catch (CameraAccessException | NullPointerException e) {
e.printStackTrace();
}
}
À partir de l'aperçu de la caméra:
private void startCamera() {
try {
cameraManager.openCamera("0", new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
cameraDevice = camera;
try {
cameraDevice.createCaptureSession(Arrays.asList(cameraSurfaceView.getHolder().getSurface(), imageReader.getSurface()),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
captureSession = session;
try {
requestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
requestBuilder.addTarget(cameraSurfaceView.getHolder().getSurface());
requestBuilder.addTarget(imageReader.getSurface());
requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
requestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
captureRequest = requestBuilder.build();
cameraReady = true;
captureSession.setRepeatingRequest(captureRequest, null, handler);
onStartButtonClick(startButton);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
Et vient ici OnImageAvailableListener du ImageReader (ce qui est mon activité principale actuellement):
@Override
public void onImageAvailable(ImageReader reader) {
reader.acquireNextImage().close();
}
Ces extraits de code résident tous dans mon activité principale actuellement. Le téléphone que j'utilise est un Motorola Moto X Play à des fins de test. Le cameraSurfaceView est juste un simple SurfaceView sans aucune personnalisation.
J'ai réussi pour obtenir un nombre de fps plus élevé en diminuant la résolution de l'aperçu mais ce n'est pas une solution idéale – masm64