Module de Programmation Android (LP PRISM AirFrance)

TD9 - Utilisation de la webcam

L'objectif de ce TD est l'utilisation des ressources matérielles au sein d'une application, en prenant l'exemple de la webcam : Pour cela, nous allons développer une application permettant de prendre une photo et affichant la photo prise (sans chercher à la sauvegarder).

Mise en place

Pour pouvoir utiliser la webcam, vous travaillerez aujourd'hui sur les tablettes fournies par l'IUT (ou sur votre propre tablette ou téléphone), mais pas avec l'émulateur.

Créer une nouvelle application, avec comme SDK minimum au moins l'API 16. Dans l'activité principale, ajouter deux boutons, qui lancent chacun une nouvelle activité différente (correspondant aux deux objectifs du TD ci-dessus). (Il y a donc en tout trois activités.)

Définir la même interface pour les deux activités filles : un bouton marqué "Cheese!", et une boîte de type ImageView occupant tout le reste de l'écran.

Pour gagner du temps, vous pouvez au lieu de cela récupérer ce squelette.

Permissions

Ajouter les lignes suivantes dans le manifeste, en dehors des balises application :

  <uses-permission android:name="android.permission.CAMERA" />
  <uses-feature
    android:name="android.hardware.camera"
    android:required="true" />
  <uses-feature android:name="android.hardware.camera.autofocus" />

On requiert l'accès à la webcam, tout en sollicitant deux fonctionnalités offertes par la plupart des webcams.

Utilisation de l'application d'appareil photo

Nous allons ici travailler dans l'une des deux activités filles.

Utilisation directe de la webcam

Nous allons ici travailler dans l'autre activité fille.

Nous allons utiliser la classe Camera, qui n'est plus conseillée depuis l'API 21 mais est encore à utiliser pour l'instant car de nombreux appareils possèdent une API plus ancienne.

Accès à la webcam

Évènement associé à la prise d'une photo

Un tel évènement est une classe implantant l'interface Camera.PictureCallback. Nous pouvons par exemple définir une telle classe de manière anonyme :
  private Camera.PictureCallback prisePhoto = new Camera.PictureCallback() {
    @Override
    public void onPictureTaken(byte[] photo, Camera camera) {
      // Action à effectuer
    }
  };
Surcharger la méthode onPictureTaken de manière à :

Prise d'une photo

Associer une méthode au clic sur le bouton. Dans cette méthode, prendre une photo en utilisant null pour les deux premiers paramètres et prisePhoto pour le troisième. (Ces différents paramètres servent à gérer les différents formats d'image possibles.)

Tester.

Prévisualisation

Avec cet appareil photo minimaliste, nous ne voyons pas ce que nous prenons en photo... Il manque une prévisualisation en temps réel de l'image vue par la webcam.

Interface

Diviser par deux la taille de la zone ImageView, et ajouter dans l'espace disponible une boîte de type FrameLayout. C'est à cette boîte que nous allons associer une prévisualisation.

Classe servant à la prévisualisation

La prévisualisation est une classe héritant de SurfaceView et implantant l'interface SurfaceHolder.Callback afin de définir les opérations à effectuer lorsque la surface est créée, détruite, et modifiée.

Voici une façon de définir cette classe :
public class Previsualisation extends SurfaceView implements SurfaceHolder.Callback {
  private Camera webcam;
  private SurfaceHolder evenement;

  // Constructeur
  public Previsualisation(Context context, Camera webcam) {
    // On appelle le constructeur de la super-classe sur le contexte
    super(context);
    // On stocke la webcam passée en argument dans un champ de la classe
    this.webcam = webcam;

    // Le SurfaceHolder permet de réagir lorsque la prévisualisation est créée ou détruite
    evenement = getHolder();
    evenement.addCallback(this);
  }

  // Cette méthode est appelée lorsque la SurfaceView est créée
  public void surfaceCreated(SurfaceHolder holder) {
    // Lorsque la surface est créée, on affiche la prévisualisation
    try {
      webcam.setPreviewDisplay(holder);
      webcam.startPreview();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  // Cette méthode est appelée lorsque la surface est détruite
  public void surfaceDestroyed(SurfaceHolder holder) {
    // Rien à faire : c'est l'activité qui s'occupe d'arrêter la webcam
  }

  // Cette méthode est appelée lorsque la surface est modifiée, par exemple en cas de rotation
  // de la tablette
  public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // On arrête la prévisualisation
    try {
      webcam.stopPreview();
    } catch (Exception e){
      e.printStackTrace();
    }

    // On relance la prévisualisation avec la nouvelle surface
    try {
      webcam.setPreviewDisplay(holder);
      webcam.startPreview();

    } catch (Exception e){
      e.printStackTrace();
    }
  }
}
Copier-coller le code dans un nouveau fichier Java. bien lire les commentaires et se reporter à la documentation pour comprendre ce que font les différentes méthodes de cette classe.

Utilisation de la prévisualisation

Compléter la méthode onResume() après avoir déclaré la webcam, afin de : Tester.

À vous de jouer

Pour l'activité utilisant l'application d'appareil photo :
  1. Ajouter une zone de texte et un bouton pour permettre à l'utilisateur de choisir la transparence de la photo.
  2. Transformer l'application pour qu'elle enregistre un film au lieu de prendre une photo.
Pour l'activité utilisant la webcam directement :
  1. Au lieu que la prévisualisation et la photo se partagent l'espace, utiliser deux fragments dont l'un va remplacer l'autre.
  2. Ajouter un bouton de retour (ou utiliser le bouton de retour de la tablette) permettant de revenir sur la prévisualisation.

Retour à la page du cours