Forums Développement Multimédia

Les formations Mediabox
Les formations Mediabox

AIR pour Android : Utilisation de la caméra - Prendre des photos

Compatible AIR 2. Cliquer pour en savoir plus sur les compatibilités.Compatible Flash CS5. Cliquer pour en savoir plus sur les compatibilités.Compatible ActionScript 3. Cliquer pour en savoir plus sur les compatibilités.Par joni (Joni), le 21 novembre 2010
Prérequis:
Avoir suivi la première partie du tutoriel.

La classe CameraRoll

Cette classe permet d’accéder à la librairie Multimédia du système Android. Cela signifie que vous pouvez accéder aussi bien aux photos qu’aux vidéos.

Attention toutefois, le gros inconvénient est que les vidéos ne peuvent pas être chargées dans l’application AIR car le format n’est pas compatible avec le Flash Player (pour l’instant, espérons le).

En revanche, vous pourrez charger les photos déjà présentes dans la librairie et même en ajouter.

Voyons un exemple d’utilisation de la classe CameraRoll en améliorant notre application.

Reprenons le code de la première partie de ce tuto et ajoutons quelques fonctionnalités à notre faux appareil photo.

Nous allons commencer par ajouter une fonction pour prendre une photo et l’enregistrer dans la librairie media (CameraRoll).

Pour cela, ajoutons un écouteur sur le bouton “shootBtn” comme ceci :

shootBtn.addEventListener(MouseEvent.CLICK,onShootHandler);

Il ne faut pas oublier de créer la fonction onShootHandler :

function onShootHandler(evt:MouseEvent):void
{
 
}

C’est dans cette fonction, qui sera appelée lorsque vous appuirez sur le bouton OK du faux appareil photo, que nous allons placer le code permettant de capturer l’image de la caméra et de l’envoyer dans la librairie.

Mais avant, nous allons créer un objet BitmapData en dehors de la fonction afin dene pas en recréer un nouveau à chaque photo. Lors des développements mobiles, il est important d’éviter de créer trop d’objets et d’essayer de réutiliser les objets déjà créés, car les appareils mobiles ne disposent pas de la même quantité de mémoire que les ordinateurs. A plus forte raison des objets gourmands comme les BitmapData qui vont consommer beaucoup de mémoire s’ils ne sont pas vidés et supprimés après utilisation.

Donc, ajoutez la ligne suivante au dessus de la ligne d’ajout d’écouteur sur le bouton “shootBtn” :

var photo:BitmapData = new BitmapData(video.width,video.height,true,0x000000);

Cette ligne permet de créer un objet BitmapData (pour plus d’informations référez-vous à la documentation) de taille égale à notre objet video placé sur la scène.

Ensuite, dans la fonction onShootHandler, ajoutons le code pour l’enregistrement :

clacAnim.play() //Cela joura l’animation du clac qui permettra de savoir que la photo a été prise
photo.draw(video,new Matrix(3,0,0,3)); //On dessine l’image de l’objet video dans le BitmapData (la matrice est là pour agrandir la photo, sinon elle est minuscule, cela vient de la résolution utilisée pour la caméra)
if(CameraRoll.supportsAddBitmapData) //On detecte si la librairie média supporte l’ajout d’image
{
	var camRoll:CameraRoll = new CameraRoll(); //On crée un nouvel objet CameraRoll
	camRoll.addBitmapData(photo); //On ajoute le BitmapData “photo” dans le CameraRoll
}

Vous pouvez déjà tester l’application ainsi. Lorsqu’elle est lancée sur votre téléphone, appuyez sur le bouton OK du faux appareil photo.

Allez ensuite dans la galerie de votre téléphone Android et dans la catégorie “Photos prises de l’appareil”. Vous verrez que la dernière photo est celle prise depuis notre application AIR.

Ajoutons maintenant une dernière fonctionnalités liée à la classe CameraRoll. Nous allons explorer le CameraRoll et charger une photo dans l’écran de visualisation du faux appareil photo.

Commencons par créer un objet Sprite qui contiendra la photo chargée depuis le CameraRoll. Créez le juste en dessous de la création de la caméra :

var contPhoto:Sprite = new Sprite();

Pour cela, nous allons ajouter une action sur le bouton “seeBtn” juste en dessous de l’ajout de l’écouteur sur “shootBtn” :

seeBtn.addEventListener(MouseEvent.CLICK,onSeeHandler);

Et on crée la fonction associée :

function onSeeHandler(evt:MouseEvent):void
{
 
}

Voyons le code de cette fonction :

if(contImage.contains(contPhoto)) //On vérifie si le MovieClip contImage (celui placé sur la scène au début) contient le clip contPhoto (celui qui contient la photo chargée)
{
	contImage.removeChild(contPhoto); //Si c’est le cas, on enlève le clip contPhoto de contImage
}
else
{
	if(CameraRoll.supportsBrowseForImage) //Sinon on vérifie que le CameraRoll supporte l’exploration d’images
	{
		var camRoll:CameraRoll = new CameraRoll(); //On crée un nouvel objet CameraRoll
		camRoll.addEventListener(MediaEvent.SELECT,loadImage); //On ajoute un écouteur MediaEvent.SELECT (cet évènement sera déclenché lorsque vous aurez selectionné une photo dans le CameraRoll)
		camRoll.browseForImage(); //On ouvre le CameraRoll pour explorer la librairie
	}
}

Il faut ajouter la fonction loadImage qui sera appelée lorsqu’une image aura été sélectionnée dans le CameraRoll :

function loadImage(evt:MediaEvent):void
{
	if(evt.data.mediaType == "image") //Si le type de media sélectionné est une image
	{
		var loader:Loader = new Loader(); //On crée un nouvel objet Loader pour charger l’image
		loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadImageComplete); //On ajoute un écouteur qui sera déclenché lorsque le chargement sera terminé
		loader.load(new URLRequest(evt.data.file.url)); //On lance le chargement de l’image
	}
}

Et enfin la fonction loadImageComplete :

function loadImageComplete(evt:Event):void
{
	contPhoto = new Sprite(); //On recrée l’objet contPhoto
	contPhoto.addChild(evt.target.content); //On ajoute l’image chargée à la liste d’affichage de contPhoto
	contImage.addChild(contPhoto); //On ajoute contPhoto à la liste d’affichage de contImage
}

Voici donc ce que donne le code complet sans les commentaires :

import flash.media.Camera;
import flash.events.MouseEvent;
import flash.display.BitmapData;
import flash.media.CameraRoll;
import flash.geom.Matrix;
import flash.events.MediaEvent;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.display.Sprite;
 
var cam:Camera = Camera.getCamera();
cam.setMode(video.width, video.height, 30);
video.attachCamera(cam);
 
var contPhoto:Sprite = new Sprite();
 
 
var photo:BitmapData = new BitmapData(video.width,video.height,true,0x000000);
 
 
shootBtn.addEventListener(MouseEvent.CLICK,onShootHandler);
seeBtn.addEventListener(MouseEvent.CLICK,onSeeHandler);
 
function onShootHandler(evt:MouseEvent):void
{
	clacAnim.play();
	photo.draw(video,new Matrix(3,0,0,3));
	trace(photo.width+" - "+photo.height);
	if(CameraRoll.supportsAddBitmapData)
	{
		var camRoll:CameraRoll = new CameraRoll();
		camRoll.addBitmapData(photo);
	}
 
}
 
function onSeeHandler(evt:MouseEvent):void
{
	if(contImage.contains(contPhoto))
	{
		contImage.removeChild(contPhoto);
	}
	else
	{
		if(CameraRoll.supportsBrowseForImage)
		{
			var camRoll:CameraRoll = new CameraRoll();
			camRoll.addEventListener(MediaEvent.SELECT,loadImage);
			camRoll.browseForImage();
		}
	}
 
}
 
function loadImage(evt:MediaEvent):void
{
	if(evt.data.mediaType == "image")
	{
		var loader:Loader = new Loader();
		loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadImageComplete);
		loader.load(new URLRequest(evt.data.file.url));
	}
}
 
function loadImageComplete(evt:Event):void
{
	contPhoto = new Sprite();
	contPhoto.addChildAt(evt.target.content,clacAnim.index+1);
	contImage.addChild(contPhoto);
}

Il est vrai que je n’ai pas parlé des imports de classe au débit du code. Normalement, Flash CS5 importe automatiquement les classes dont vous avez besoin au fur et à mesure que vous créez les nouveaux objets. Si ce n’est pas le cas, vous aurez une erreur à la compilation vous disant que la définition dela classe est introuvable. Vous pourrez alors les ajouter manuellement en vous fiant au code complet.

Conclusion

Voici donc un exemple assez complet des possibilités de la classe CameraRoll. Vous voyez que couplée à la classe Camera, il est possible d'interagir avec certaines parties du système Android. Dans la prochaine partie du tutoriel, nous verrons la classe CameraUI qui permet d'utiliser le système natif d'Android de capture de photo et de vidéo.

Les sources

Vous pouvez télécharger la source complète de ces deux premières parties du tutoriel ainsi que l'application finale.