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 :
- Configurez un élément
CameraXConfig.Provider
(facultatif). - Ajoutez
PreviewView
à votre mise en page. - Demandez un élément
ProcessCameraProvider
. - Au moment de créer
View
, vérifiezProcessCameraProvider
. - 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 surTextureView
etPreview.SurfaceProvider
. - Récupérer l'élément
SurfaceTexture
à partir deTextureView
et le définir surPreview.SurfaceProvider
. - Obtenir l'élément
Surface
à partir deSurfaceView
et le définir surPreview.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 :
- Créez un élément
Preview
. - Précisez l'option
LensFacing
de la caméra souhaitée. - Associez la caméra sélectionnée et tous les cas d'utilisation au cycle de vie.
- 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 de l'affichage des flux d'aperçu
- Type d'échelle de l'image d'aperçu
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émentSurfaceView
pour afficher le flux vidéo, mais revient à un élémentTextureView
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émentTextureView
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
etFIT_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émentPreviewView
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
etFILL_END
pour le recadrage. Si une vidéo ne correspond pas au formatPreviewView
, seule une partie du contenu est visible, mais la vidéo occupe tout l'élémentPreviewView
.
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 :
- Mise à l'échelle de la vidéo :
- Pour les types de mise à l'échelle
FIT_*
, utilisezmin(dst.width/src.width, dst.height/src.height)
. - Pour les types de mise à l'échelle
FILL_*
, utilisezmax(dst.width/src.width, dst.height/src.height)
.
- Pour les types de mise à l'échelle
- 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émentPreviewView
de destination. - Pour
FIT_START/FILL_START
, alignez la vidéo mise à l'échelle et l'élémentPreviewView
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émentPreviewView
de destination par rapport à leur angle inférieur droit respectif.
- Pour
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 :
L'image suivante illustre le processus de mise à l'échelle de FIT_START
/ FIT_CENTER
/ FIT_END
:
Le processus fonctionne comme ceci :
- 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. - 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 dePreviewView
. Les colonnes de début et de fin de 240 pixels dePreviewView
sont vides. - Pour
FIT_START
, alignez l'image vidéo sur le début (coin supérieur gauche) de la fenêtre dePreviewView
. Les colonnes de fin de 480 pixels dePreviewView
sont vides. - Pour
FIT_END
, alignez l'image vidéo avec la fin (coin inférieur droit) de la fenêtre dePreviewView
. Les colonnes de début de 480 pixels dePreviewView
sont vides.
- Pour
L'image suivante illustre le processus de mise à l'échelle de FILL_START
/ FILL_CENTER
/ FILL_END
:
Le processus fonctionne comme ceci :
- 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 dePreviewView
. - 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.
- Pour
Ressources supplémentaires
Pour en savoir plus sur CameraX, consultez les ressources supplémentaires suivantes.
Atelier de programmation
Exemple de code