Capturez l'image sans prévisualisation à l'aide de l'API camera2

Ce que je souhaite atteindre est de capturer une image sans afficher l'aperçu, en envoyant directement la sortie à un ImageReader . J'ai utilisé l' exemple Camera2Basic comme point de départ. Cependant, le rappel de mon ImageReader n'est jamais appelé, d'où aucune image n'est envoyée à sa Surface . Dois-je vraiment afficher un aperçu d'abord?

C'est le code de la caméra, qui est commandé à la suite du flux des rappels asynchrones:

  • Comment faire une boucle ViewPager?
  • J'essaie de rechercher des endroits proches tels que des banques, des restaurants, des guichets automatiques dans la zone dessinée sur google maps dans Android
  • Comment lancer une caméra avant avec intention?
  • Plusieurs filateurs et onItemSelected
  • Est-il possible de déplacer le DB interne vers la carte SD?
  • Détecter si TextView dans ListView est délimité
  •  private ImageReader imageReader; private Handler backgroundHandler; private HandlerThread backgroundThread; private String cameraId; private CameraDevice cameraDevice; private CameraCaptureSession cameraCaptureSession; @Override public void onCreate() { setupCamera2(); } private void setupCamera2() { CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); try { for (String cameraId : manager.getCameraIdList()) { CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); if (characteristics.get(CameraCharacteristics.LENS_FACING) != CameraCharacteristics.LENS_FACING_FRONT) { continue; } this.cameraId = cameraId; int[] picSize = Settings.getPictureSize(); int picWidth = picSize[0]; int picHeight = picSize[1]; imageReader = ImageReader.newInstance(picWidth, picHeight, ImageFormat.JPEG, 2); imageReader.setOnImageAvailableListener(onImageAvailableListener, backgroundHandler); } } catch (CameraAccessException | NullPointerException e) { e.printStackTrace(); } } private void openCamera2() { CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); try { manager.openCamera(cameraId, cameraStateCallback, backgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } private final CameraDevice.StateCallback cameraStateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice device) { cameraDevice = device; createCameraCaptureSession(); } @Override public void onDisconnected(CameraDevice cameraDevice) {} @Override public void onError(CameraDevice cameraDevice, int error) {} }; private void createCaptureSession() { List<Surface> outputSurfaces = new LinkedList<>(); outputSurfaces.add(imageReader.getSurface()); try { cameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession session) { cameraCaptureSession = session; } @Override public void onConfigureFailed(CameraCaptureSession session) {} }, null); } catch (CameraAccessException e) { e.printStackTrace(); } } private final ImageReader.OnImageAvailableListener onImageAvailableListener = new ImageReader.OnImageAvailableListener() { @Override public void onImageAvailable(ImageReader reader) { createCaptureRequest(); } }; private void createCaptureRequest() { try { CaptureRequest.Builder requestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); requestBuilder.addTarget(imageReader.getSurface()); // Focus requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); // Orientation int rotation = windowManager.getDefaultDisplay().getRotation(); requestBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation)); cameraCaptureSession.capture(requestBuilder.build(), camera2Callback, null); } catch (CameraAccessException e) { e.printStackTrace(); } } 

  • Clavier doux spécifique à l'application Android
  • Un moyen approprié de donner des données initiales aux fragments?
  • Comment fonctionne getAltitude () d'Android GPS Location Works
  • ViewPager: Entrée récursive pour exécuter Transitions en attente
  • Android Intention de démarrer Activité principale de l'application
  • Comment ajouter des tuiles à Google Maps et les animer, c'est-à-dire les remplacer par de nouvelles carreaux en continu
  • 3 Solutions collect form web for “Capturez l'image sans prévisualisation à l'aide de l'API camera2”

    Vous devez capturer des photos dans la fonction "OnConfigure" mais pas surImageDisponible.

     public void onConfigured(CameraCaptureSession session) { cameraCaptureSession = session; createCaptureRequest(); } 

    Dans cette fonction "onImageAvailable", vous devez enregistrer des images,

     Image image = mImageReader.acquireLatestImage(); ByteBuffer buffer = image.getPlanes()[0].getBuffer(); byte[] bytes = new byte[buffer.remaining()]; buffer.get(bytes); try { save(bytes, file); } catch (IOException e) { e.printStackTrace(); } image.close(); 

    La fonction "OnImageAvailable" sera invoquée après session.capture ().

    Puisque j'ai beaucoup compris comment cela fonctionne, voici un service Android fonctionnel minimal qui peut traiter les données d'image. Cela nécessite probablement un certain temps après la création avant que vous puissiez appeler le démarrage du service!

     import android.app.Service; import android.content.Intent; import android.graphics.ImageFormat; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCaptureSession; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraDevice; import android.hardware.camera2.CameraManager; import android.hardware.camera2.CaptureRequest; import android.media.Image; import android.media.ImageReader; import android.os.IBinder; import android.util.Log; import java.util.Arrays; public class VideoProcessingService extends Service { private static final String TAG = "VideoProcessing"; private static final int CAMERA = CameraCharacteristics.LENS_FACING_FRONT; private CameraDevice camera; private CameraCaptureSession session; private ImageReader imageReader; private CameraDevice.StateCallback cameraStateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice camera) { VideoProcessingService.this.camera = camera; } @Override public void onDisconnected(CameraDevice camera) {} @Override public void onError(CameraDevice camera, int error) {} }; private CameraCaptureSession.StateCallback sessionStateCallback = new CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession session) { VideoProcessingService.this.session = session; try { session.setRepeatingRequest(createCaptureRequest(), null, null); } catch (CameraAccessException e){ Log.e(TAG, e.getMessage()); } } @Override public void onConfigureFailed(CameraCaptureSession session) {} }; private ImageReader.OnImageAvailableListener onImageAvailableListener = new ImageReader.OnImageAvailableListener() { @Override public void onImageAvailable(ImageReader reader){ Image img = reader.acquireLatestImage(); processImage(img); img.close(); } }; @Override public void onCreate() { CameraManager manager = (CameraManager) getSystemService(CAMERA_SERVICE); try { manager.openCamera(getCamera(manager), cameraStateCallback, null); imageReader = ImageReader.newInstance(320, 240, ImageFormat.YUV_420_888, 30 * 600); //fps * 10 min imageReader.setOnImageAvailableListener(onImageAvailableListener, null); } catch (CameraAccessException e){ Log.e(TAG, e.getMessage()); } } /** * Return the Camera Id which matches the field CAMERA. */ public String getCamera(CameraManager manager){ try { for (String cameraId : manager.getCameraIdList()) { CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); int cOrientation = characteristics.get(CameraCharacteristics.LENS_FACING); if (cOrientation == CAMERA) { return cameraId; } } } catch (CameraAccessException e){ e.printStackTrace(); } return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { try { camera.createCaptureSession(Arrays.asList(imageReader.getSurface()), sessionStateCallback, null); } catch (CameraAccessException e){ Log.e(TAG, e.getMessage()); } return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { try { session.abortCaptures(); } catch (CameraAccessException e){ Log.e(TAG, e.getMessage()); } session.close(); } /** * Process image data as desired. */ private void processImage(Image image){ //Process image data } private CaptureRequest createCaptureRequest() { try { CaptureRequest.Builder builder = camera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); builder.addTarget(imageReader.getSurface()); return builder.build(); } catch (CameraAccessException e) { Log.e(TAG, e.getMessage()); return null; } } @Override public IBinder onBind(Intent intent) { return null; } } 

    Puisque j'ai longuement lutté contre l'API CAMERA2, je cherchais comment prendre des photos sans aperçu de toutes les caméras disponibles sur le périphérique, j'ai créé un projet sur GitHub qui fait exactement ce que vous voulez (et peut-être plus) https : //github.com/hzitoun/android-camera2-secret-picture-kerker

    Entrez la description de l'image ici

    Espérons que cela a aidé 🙂

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.