Intégrer un aperçu

Lorsque vous ajoutez un aperçu à votre application, utilisez PreviewView, un élément View qui peut être recadré, mis à l'échelle et orienté pour un affichage approprié.

L'aperçu de l'image est diffusé vers une surface à l'intérieur de PreviewView lorsque la caméra devient active.

Utiliser une PreviewView

L'intégration d'un aperçu pour CameraX avec PreviewView implique les étapes suivantes, détaillées par la suite :

  1. Configurez un élément CameraXConfig.Provider (facultatif).
  2. Ajoutez PreviewView à votre mise en page.
  3. Demandez un élément ProcessCameraProvider.
  4. Au moment de créer View, vérifiez ProcessCameraProvider.
  5. Sélectionnez une caméra, puis associez-y le cycle de vie et les cas d'utilisation.

L'utilisation de PreviewView présente certaines limites. Si vous utilisez PreviewView, vous ne pouvez effectuer aucune des actions suivantes :

  • Créer un élément SurfaceTexture à définir sur TextureView et Preview.SurfaceProvider.
  • Récupérer l'élément SurfaceTexture à partir de TextureView et le définir sur Preview.SurfaceProvider.
  • Obtenir l'élément Surface à partir de SurfaceView et le définir sur Preview.SurfaceProvider.

Si l'une de ces actions se produit, Preview cesse de diffuser des frames sur PreviewView.

Ajouter une PreviewView à votre mise en page

L'exemple suivant montre un élément PreviewView dans une mise en page :

<FrameLayout
    android:id="@+id/container">
        <androidx.camera.view.PreviewView
            android:id="@+id/previewView" />
</FrameLayout>

Demander un CameraProvider

Le code suivant montre comment demander un élément CameraProvider :

Kotlin

import androidx.camera.lifecycle.ProcessCameraProvider
import com.google.common.util.concurrent.ListenableFuture

class MainActivity : AppCompatActivity() {
    private lateinit var cameraProviderFuture : ListenableFuture<ProcessCameraProvider>
    override fun onCreate(savedInstanceState: Bundle?) {
        cameraProviderFuture = ProcessCameraProvider.getInstance(this)
    }
}

Java

import androidx.camera.lifecycle.ProcessCameraProvider
import com.google.common.util.concurrent.ListenableFuture

public class MainActivity extends AppCompatActivity {
    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
    }
}

Vérifier la disponibilité de CameraProvider

Après avoir demandé un élément CameraProvider, vérifiez que son initialisation a réussi lors de la création de la vue. Pour ce faire, entrez le code suivant :

Kotlin

cameraProviderFuture.addListener(Runnable {
    val cameraProvider = cameraProviderFuture.get()
    bindPreview(cameraProvider)
}, ContextCompat.getMainExecutor(this))

Java

cameraProviderFuture.addListener(() -> {
    try {
        ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
        bindPreview(cameraProvider);
    } catch (ExecutionException | InterruptedException e) {
        // No errors need to be handled for this Future.
        // This should never be reached.
    }
}, ContextCompat.getMainExecutor(this));

Pour un exemple de la fonction bindPreview utilisée dans cet exemple, consultez le code fourni dans la section suivante.

Sélectionner une caméra et y lier le cycle de vie et les cas d'utilisation

Après avoir créé et confirmé l'élément CameraProvider, procédez comme suit :

  1. Créez un élément Preview.
  2. Précisez l'option LensFacing de la caméra souhaitée.
  3. Associez la caméra sélectionnée et tous les cas d'utilisation au cycle de vie.
  4. Connectez Preview à PreviewView.

Le code suivant sert d'exemple :

Kotlin

fun bindPreview(cameraProvider : ProcessCameraProvider) {
    var preview : Preview = Preview.Builder()
            .build()

    var cameraSelector : CameraSelector = CameraSelector.Builder()
          .requireLensFacing(CameraSelector.LENS_FACING_BACK)
          .build()

    preview.setSurfaceProvider(previewView.getSurfaceProvider())

    var camera = cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, preview)
}

Java

void bindPreview(@NonNull ProcessCameraProvider cameraProvider) {
    Preview preview = new Preview.Builder()
            .build();

    CameraSelector cameraSelector = new CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build();

    preview.setSurfaceProvider(previewView.getSurfaceProvider());

    Camera camera = cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, preview);
}

Notez que bindToLifecycle() renvoie un objet Camera. Pour en savoir plus sur le contrôle de la sortie de la caméra, comme le zoom et l'exposition, consultez Sortie de la caméra.

Vous avez terminé l'intégration de l'aperçu de la caméra. Créez votre application, puis vérifiez que l'aperçu s'affiche dans votre application et fonctionne comme prévu.

Commandes supplémentaires pour PreviewView

L'élément PreviewView de CameraX fournit des API supplémentaires pour configurer des propriétés telles que :

Mode d'intégration

PreviewView peut utiliser l'un des modes suivants pour afficher un flux d'aperçu sur l'élément View cible :

  • PERFORMANCE est le mode par défaut. PreviewView utilise un élément SurfaceView pour afficher le flux vidéo, mais revient à un élément TextureView dans certains cas. SurfaceView dispose d'une surface de dessin dédiée, qui a plus de chances d'être intégrée avec une superposition matérielle par le compositeur matériel interne, en particulier lorsqu'il n'y a pas d'autres éléments d'interface utilisateur (comme des boutons) au-dessus de la vidéo d'aperçu. Grâce à l'affichage avec une superposition matérielle, les images vidéo évitent un chemin GPU, ce qui peut réduire la consommation d'énergie et la latence de la plate-forme.

  • Mode COMPATIBLE Dans ce mode, PreviewView utilise un élément TextureView qui, contrairement à SurfaceView, ne dispose pas d'une surface de dessin dédiée. Le rendu de la vidéo est donc effectué de sorte qu'elle puisse être affichée. Au cours de cette étape supplémentaire, l'application peut effectuer d'autres traitements, comme la mise à l'échelle et la rotation des vidéos, sans restriction.

Utilisez PreviewView.setImplementationMode() pour sélectionner le mode d'intégration adapté à votre application. Si le mode PERFORMANCE par défaut ne convient pas à votre application, l'exemple de code suivant montre comment définir le mode COMPATIBLE :

Kotlin

// viewFinder is a PreviewView instance
viewFinder.implementationMode = PreviewView.ImplementationMode.COMPATIBLE

Type d'échelle

Lorsque la résolution de l'aperçu vidéo diffère des dimensions de votre élément PreviewView cible, le contenu vidéo doit être ajusté à la vue, soit par recadrage, soit par affichage au format letterbox (en conservant le format d'origine). PreviewView fournit les ScaleTypes suivants à cette fin :

  • FIT_CENTER, FIT_START et FIT_END pour l'affichage au format letterbox. La taille du contenu intégral de la vidéo est ajustée (à la hausse ou à la baisse) pour atteindre la taille maximale pouvant être affichée dans l'élément PreviewView cible. Toutefois, même si toute l'image vidéo est visible, certaines parties de l'écran peuvent être vides. Selon le type d'échelle que vous choisissez parmi ces trois-ci, l'image vidéo s'aligne sur le centre, le début ou la fin de la vue cible.

  • FILL_CENTER, FILL_START et FILL_END pour le recadrage. Si une vidéo ne correspond pas au format PreviewView, seule une partie du contenu est visible, mais la vidéo occupe tout l'élément PreviewView.

Par défaut, CameraX utilise le type d'échelle FILL_CENTER. Utilisez PreviewView.setScaleType() pour définir le type d'échelle le mieux adapté à votre application. L'exemple de code suivant définit le type d'échelle FIT_CENTER :

Kotlin

// viewFinder is a PreviewView instance
viewFinder.scaleType = PreviewView.ScaleType.FIT_CENTER

Pour afficher une vidéo, procédez comme suit :

  1. Mise à l'échelle de la vidéo :
    • Pour les types de mise à l'échelle FIT_*, utilisez min(dst.width/src.width, dst.height/src.height).
    • Pour les types de mise à l'échelle FILL_*, utilisez max(dst.width/src.width, dst.height/src.height).
  2. Alignez la vidéo mise à l'échelle sur la destination PreviewView :
    • Pour FIT_CENTER/FILL_CENTER, centrez la vidéo mise à l'échelle et l'élément PreviewView de destination.
    • Pour FIT_START/FILL_START, alignez la vidéo mise à l'échelle et l'élément PreviewView de destination par rapport à leur angle supérieur gauche respectif.
    • Pour FIT_END/FILL_END, alignez la vidéo mise à l'échelle et l'élément PreviewView de destination par rapport à leur angle inférieur droit respectif.

Par exemple, voici une vidéo source de 640 x 480 pixels et un élément PreviewView de destination de 1 920 x 1 080 pixels :

Image montrant une vidéo de 640 x 480 pixels par rapport à un aperçu de 1 920 x 1 080 pixels

L'image suivante illustre le processus de mise à l'échelle de FIT_START / FIT_CENTER / FIT_END :

Image montrant les processus de mise à l&#39;échelle de FIT_START, FIT_CENTER et FIT_END

Le processus fonctionne comme ceci :

  1. Ajustez l'image vidéo (en conservant le format d'origine) avec min(1920/640, 1080/480) = 2.25 pour obtenir une image vidéo intermédiaire de 1 440 x 1 080 pixels.
  2. Alignez l'image vidéo de 1 440 x 1 080 pixels avec l'élément PreviewView de 1 920 x 1 080 pixels.
    • Pour FIT_CENTER, alignez l'image vidéo sur le centre de la fenêtre de PreviewView. Les colonnes de début et de fin de 240 pixels de PreviewView sont vides.
    • Pour FIT_START, alignez l'image vidéo sur le début (coin supérieur gauche) de la fenêtre de PreviewView. Les colonnes de fin de 480 pixels de PreviewView sont vides.
    • Pour FIT_END, alignez l'image vidéo avec la fin (coin inférieur droit) de la fenêtre de PreviewView. Les colonnes de début de 480 pixels de PreviewView sont vides.

L'image suivante illustre le processus de mise à l'échelle de FILL_START / FILL_CENTER / FILL_END :

Image illustrant le processus de mise à l&#39;échelle de FILL_START, FILL_CENTER et FILL_END

Le processus fonctionne comme ceci :

  1. Ajustez l'image vidéo avec max(1920/640, 1080/480) = 3 pour obtenir une image vidéo intermédiaire de 1 920 x 1 440 pixels, ce qui est supérieur à la taille de PreviewView.
  2. Recadrez la vidéo de 1 920 x 1 440 pixels afin qu'elle s'adapte à la fenêtre de PreviewView de 1 920 x 1 080 pixels.
    • Pour FILL_CENTER, recadrez au format 1 920 x 1 080 pixels à partir du centre de la vidéo adaptée au format 1 920 x 1 440 pixels. Les 180 lignes inférieures et supérieures de la vidéo ne sont pas visibles.
    • Pour FILL_START, recadrez au format 1 920 x 1 080 pixels à partir du début de la vidéo adaptée au format 1 920 x 1 440 pixels. Les 360 lignes inférieures de la vidéo ne sont pas visibles.
    • Pour FILL_END, recadrez au format 1 920 x 1 080 pixels à partir de la fin de la vidéo adaptée au format 1 920 x 1 440 pixels. Les 360 lignes supérieures de la vidéo ne sont pas visibles.

Ressources supplémentaires

Pour en savoir plus sur CameraX, consultez les ressources supplémentaires suivantes.

Atelier de programmation

  • Premiers pas avec CameraX
  • Exemple de code

  • Applications exemples de CameraX