Developpement Windows Phone – partie 27


Développer avec l’appareil photo de Windows Phone

Cet article fait partie d’une série d’articles sur le développement Windows Phone. Il s’agit d’une traduction des articles se trouvant sur la MSDN.

Sommaire

Bien débuter et fondamentaux

Visuels et média

Travailler avec les données

Sondes et autres fonctionnalités spécifiques au téléphone


Développer avec l’appareil photo de Windows Phone

Silverlight pour Windows Phone comprend plusieurs outils faciles à utiliser pour l’exploitation de la caméra et des photos. Ici, nous allons montrer comment prendre et enregistrer des photos avec l'appareil photo du Windows Phone, sélectionner et afficher des photos depuis la bibliothèque d’images de Windows Phone.

Cet article est divisé en plusieurs sections :

Télécharger le code source complet de ce tutoriel.

 

Créer une interface utilisateur pour l’appareil photo et l’affichage des images

Lancez Visual Studio et commencez un projet de type "Silverlight pour Windows Phone". Puis créez une interface utilisateur (UI) qui comporte les éléments suivants:

  • Deux champs TextBlock - un avec un nom significatif qui permettra d'afficher des messages d'état, et un TextBlock qui affiche simplement: «Débranchez votre téléphone à partir du logiciel Zune pour le faire fonctionner"
  • Un objet Image avec un nom significatif qui aura sa source dynamiquement mise à jour pour refléter la nouvelle image qui a été prise ou choisie.
  • Trois boutons avec des noms significatifs qui seront utilisés pour prendre une nouvelle photo, afficher une photo existante, et enregistrer la photo affichée dans l’espace de stockage du téléphone. Dans cet article, ces boutons seront respectivement appelés takePhotoButton, choosePhotoButton, et savePhotoButton.

Une disposition de ces éléments est fournie ci-dessous.
clip_image001

XAML

Code Snippet
  1. <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
  2.     <Button Content="Take Photo" Height="72" HorizontalAlignment="Left" Margin="12,6,0,0" Name="button1" VerticalAlignment="Top" Width="189" Click="button1_Click" />
  3.     <Image Height="308" HorizontalAlignment="Left" Margin="27,275,0,0" Name="myImage" Stretch="Fill" VerticalAlignment="Top" Width="406"/>
  4.     <Button Content="Choose Existing" Height="72" HorizontalAlignment="Left" Margin="194,6,0,0" Name="button2" VerticalAlignment="Top" Width="239" Click="button2_Click" />
  5.     <TextBlock Height="30" HorizontalAlignment="Left" Margin="27,162,0,0" Name="textBlock1" Text="Disconnect phone from Zune software to run!" VerticalAlignment="Top" Width="406" />
  6.     <Button Content="Save Current Photo to Library" Height="72" HorizontalAlignment="Left" Margin="12,84,0,0" Name="savePhotoButton" VerticalAlignment="Top" Width="419" IsEnabled="False" Click="savePhotoButton_Click" />
  7.     <TextBlock Height="71" HorizontalAlignment="Left" Margin="29,197,0,0" Name="statusText" Text="" VerticalAlignment="Top" Width="402" Foreground="Red" TextWrapping="Wrap" />
  8. </Grid>

En tant que dernière étape avant de coder, ajoutez la référence Microsoft.Xna.Framework. Nous allons utiliser l'espace de noms Microsoft.Xna.Framework.Media de cet assembly pour enregistrer des images à la bibliothèque de média du téléphone, et il doit être référencé par votre projet avant que l'un de ses types, événements ou méthodes puisse l’utiliser dans votre application.

Pour ajouter l’espace de nom Microsoft.Xna.Framework à votre application:

1. Dans le Solution Explorer, cliquez-droit sur References, puis sélectionnez Add Reference.

2. Sélectionnez Microsoft.Xna.Framework dans la liste, puis cliquez sur OK.

Prendre, sélectionner, et afficher des images

Dans le Solution Explorer, ouvrez le fichier MainPage.xaml.cs, et ajoutez les lignes de codes suivantes en haut de la page, laisser les références existantes (par défaut) en place.

C#

Code Snippet
  1. using Microsoft.Phone.Tasks;
  2. using System.Windows.Media.Imaging;
  3. using System.IO;
  4. using System.IO.IsolatedStorage;
  5. using Microsoft.Xna.Framework.Media;

Visual Basic

Code Snippet
  1. Imports Microsoft.Phone.Tasks
  2. Imports System.Windows.Media.Imaging
  3. Imports System.IO
  4. Imports System.IO.IsolatedStorage
  5. Imports Microsoft.Xna.Framework.Media

Cela permet à votre code d'accéder aux espaces de noms nécessaires pour ouvrir l'application appareil photo du téléphone pour prendre une photo, utiliser un objet Bitmap réinscriptible pour stocker les données d'une image temporaire, utiliser un flux de mémoire pour convertir l'image en un fichier, sauvegarder une photo dans le l’espace de stockage interne du téléphone, et déplacer une image à partir de l’Isolated Storage du téléphone à la bibliothèque médias du téléphone.

Pour la sélection de photos et l'utilisation de la caméra, il nous faudra une coordination entre plusieurs méthodes, nous allons donc ajouter quelques membres de données à la classe principale. Deux d'entre elles seront des objets Chooser, qui permettent aux applications de décharger le contrôle à la fonctionnalité native du système d'exploitation du téléphone afin de faciliter les choses comme le choix d'un contact à partir d'une liste, de prendre une photo, ou de sélectionner une photo depuis la pellicule photo de l’appareil photo du téléphone. Un autre objet sera une image bitmap que nous utilisons pour stocker les informations de l’image temporaire, à savoir, les images que nous avons choisies, soit de la pellicule ou simplement prises avec l'appareil lui-même

C#

Code Snippet
  1. public partial class MainPage : PhoneApplicationPage
  2.         {
  3.             // Declare the CameraCaptureTask object with page scope.
  4.             CameraCaptureTask cameraCaptureTask;
  5.             PhotoChooserTask photoChooserTask;
  6.             BitmapImage bmp;
  7.  
  8.             ...

Visual Basic

Code Snippet
  1. Partial Public Class MainPage
  2.         Inherits PhoneApplicationPage
  3.         ' Declare the CameraCaptureTask object with page scope.
  4.         Private cameraCaptureTask As CameraCaptureTask
  5.         Private photoChooserTask As PhotoChooserTask
  6.         Private bmp As BitmapImage
  7.         ...

cameraCaptureTask et photoChooserTask auront besoin d'avoir des gestionnaires d'événements câblés qui se déclencheront quand une photo sera prise ou choisie dans la bibliothèque d'images du téléphone. Cela signifie que les deux événements suivants doivent être gérés:

1. L’événement Completed de cameraCaptureTask.

2. L’événement Completed de photoChooserTask


Dans les deux cas, nous voulons juste afficher l'image à l'écran, et parce que les évènements Completed envoient le même type d'objet (un objet PhotoResult) à leurs gestionnaires , nous allons utiliser une seule méthode pour gérer ces deux évènements. Nous appellerons cette méthode photoCaptureOrSelectionCompleted, et elle prendra une photo qui a été soit prise par la caméra ou sélectionnée à partir de la bibliothèque d'images, et l’affichera sur l'écran. Le câblage des deux évènements à cette nouvelle méthode est fait dans la fonction startup, MainPage, résultant ce qui suit:

C#

Code Snippet
  1. public MainPage()
  2.             {
  3.                 InitializeComponent();
  4.                 // Initialize the Chooser objects and assign the handlers for their "Completed" events
  5.                 cameraCaptureTask = new CameraCaptureTask();
  6.                 cameraCaptureTask.Completed += new EventHandler<PhotoResult>(photoCaptureOrSelectionCompleted);
  7.                 photoChooserTask = new PhotoChooserTask();
  8.                 photoChooserTask.Completed += new EventHandler<PhotoResult<(photoCaptureOrSelectionCompleted);
  9.             }

Visual Basic

Code Snippet
  1. Partial Public Class MainPage
  2.         Inherits PhoneApplicationPage
  3.         ' Declare the CameraCaptureTask object with page scope.
  4.         Private cameraCaptureTask As CameraCaptureTask
  5.         Private photoChooserTask As PhotoChooserTask
  6.         Private bmp As BitmapImage
  7.     End Class

Plus tôt, lors de la création de l'interface utilisateur, nous avons ajouté une image à l'écran appelée myImage, mais nous n'avions pas fixé sa source, laissant donc le champ vide. Quand l’évènement photoCaptureOrSelectionCompleted est déclenché, nous savons que l'utilisateur a pris ou sélectionné une image, il est donc temps de définir la Source de myImage à cette image, puis redimensionner celle-ci afin qu'elle s'adapte à la zone d'affichage de myImage. Nous allons également mettre à jour le statut du texte du TextBlock si nécessaire. Enfin, nous allons activer le bouton qui permet à l'utilisateur d'enregistrer l'image affichée.

La propriété Stretch de l’objet Image détermine la façon dont l'image sera dimensionnée pour s'adapter aux dimensions de myImage, nous utilisons ici Stretch.Uniform pour préserver le ratio original de l’image.

Ainsi, nous avons la possibilité de sauvegarder plus tard cette image si l'utilisateur le souhaite, nous allons utiliser le bitmap que nous avons créé plus tôt, appelé bmp, pour recevoir les nouvelles données de l’image, puis l’affecter en tant que source de myImage afin qu'il s’affiche sur l'écran. (Dans une autre méthode que nous mettrons en œuvre plus tard, le contenu de bmp pourra être sauvegardé sur l’espace de stockage interne du téléphone) La méthode finale photoCaptureOrSelectionCompleted ressemble à ceci:

C#

Code Snippet
  1. void photoCaptureOrSelectionCompleted(object sender, PhotoResult e)
  2.         {
  3.             if (e.TaskResult == TaskResult.OK)
  4.             {
  5.                 bmp = new BitmapImage();
  6.                 bmp.SetSource(e.ChosenPhoto);
  7.                 myImage.Source = bmp;
  8.                 myImage.Stretch = Stretch.Uniform;
  9.                 // swap UI element states
  10.                 savePhotoButton.IsEnabled = true;
  11.                 statusText.Text = "";
  12.             }
  13.             else
  14.             {
  15.                 savePhotoButton.IsEnabled = false;
  16.                 statusText.Text = "Task Result Error: " + e.TaskResult.ToString();
  17.             }
  18.         }

Visual Basic

Code Snippet
  1. Private Sub photoCaptureOrSelectionCompleted(sender As Object, e As PhotoResult)
  2.     If e.TaskResult = TaskResult.OK Then
  3.         bmp = New BitmapImage()
  4.         bmp.SetSource(e.ChosenPhoto)
  5.         myImage.Source = bmp
  6.         myImage.Stretch = Stretch.Uniform
  7.         ' swap UI element states
  8.         savePhotoButton.IsEnabled = True
  9.         statusText.Text = ""
  10.     Else
  11.         savePhotoButton.IsEnabled = False
  12.         statusText.Text = "Task Result Error: " & e.TaskResult.ToString()
  13.     End If
  14. End Sub

Maintenant nous câblons les boutons que nous avons placés dans l'interface utilisateur pour lancer un Chooser qui prendra ou sélectionnera une image. Retournez au Designer de l’interface utilisateur et double-cliquez sur le bouton «Take Photo ». Cela va créer une fonction de gestionnaire d’évènement vide qui se déclenchera lorsque le bouton sera cliqué. Notre bouton est nommé takePhotoButton, et il ne nécessite qu'une seule ligne de code pour lancer le Chooser. L'évènement Completed se déclenchera lorsque la photo sera prise. Le résultat est une fonction très simple nommée takePhotoButton_Click:

C#

Code Snippet
  1. // The camera Chooser is shown in response to a button click.
  2. private void takePhotoButton_Click(object sender, RoutedEventArgs e)
  3. {
  4.     cameraCaptureTask.Show();
  5. }

Visual Basic

Code Snippet
  1. ' The camera Chooser is shown in response to a button click.
  2. Private Sub takePhotoButton_Click(sender As Object, e As RoutedEventArgs)
  3.     cameraCaptureTask.Show()
  4. End Sub

Maintenant, double-cliquez sur le bouton «Choose Existing» que nous avons nommé choosePhotoButton. Une fois encore, une seule ligne de code est nécessaire pour lancer le Chooser qui sélectionnera une photo, résultant une méthode choosePhotoButton_Click qui ressemble à ceci:

C#

Code Snippet
  1. // The photo Chooser shown in response to a button click.
  2. private void choosePhotoButton_Click(object sender, RoutedEventArgs e)
  3. {
  4.     photoChooserTask.Show();
  5. }

Visual Basic

Code Snippet
  1. ' The photo Chooser shown in response to a button click.
  2. Private Sub choosePhotoButton_Click(sender As Object, e As RoutedEventArgs)
  3.     photoChooserTask.Show()
  4. End Sub

L'application est maintenant capable de capturer et de choisir des images existantes et de les afficher à l'écran dans des proportions correctes.
Comme l'avertissement dans l'interface utilisateur l’indique, le téléphone doit être déconnecté du logiciel Zune pour que les Choosers se lancent.

Sauvegarde des images dans la bibliothèque d’images

Afin d'enregistrer l'image dans la bibliothèque du téléphone, celle-ci devra être encodée en premier en JPEG en utilisant la classe d’Extensions de l'espace de noms System.Windows.Media.Imaging. Ensuite, l'assembly XNA que nous avons importé, sera utilisé pour l'interface avec la classe MediaLibrary, dont la méthode SavePicture écrira l’image dans la bibliothèque d'images du téléphone, où elle pourra être synchronisée à l'ordinateur, vue dans un diaporama, etc.

Nous allons écrire un fichier temporaire JPEG pour le stockage interne du téléphone, connu sous le nom d’Isolated Storage, car ce processus implique deux étapes de sauvegarde de l’image au format JPEG et par la suite nous importerons celle-ci dans la bibliothèque. En d’autres termes, l’Isolated Storage pour Windows Phone assigne un espace unique et un fichier sécurisé pour chaque application du téléphone. Nous n'allons pas entrer dans les détails de l'utilisation de l’Isolated Storage ici, nous avons juste besoin d'utiliser l'espace de stockage de notre application pour écrire notre fichier temporaire JPEG. Cela implique de créer en premier un fichier vide, puis en lui attribuant un contenu. Le type WriteableBitmap sera utilisé pour cette tâche, en recevant le contenu de bmp de notre image temporaire crée plus tôt. Enfin, nous voulons mettre à jour la propriété statusText du TextBlock lorsque nous avons un résultat de la tentative de sauvegarde de l'image.

Retournez au concepteur d'interface utilisateur et double-cliquez sur le bouton “Save Current Photo to Library », que nous avons nommé savePhotoButton. Comme avec les autres boutons nous avons un gestionnaire d’évènement vide sur l’évènement Click du bouton. Pour couvrir toutes les fonctionnalités décrites, une fois mise en œuvre, la version finale de la méthode savePhotoButton_Click ressemble à ceci:

C#

Code Snippet
  1. private void savePhotoButton_Click(object sender, RoutedEventArgs e)
  2.         {
  3.             try
  4.             {
  5.                 // Create a filename for JPEG file in isolated storage.
  6.                 String tempJPEG = "TempJPEG";
  7.                 // Create virtual store and file stream. Check for duplicate tempJPEG files.
  8.                 var myStore = IsolatedStorageFile.GetUserStoreForApplication();
  9.                 if (myStore.FileExists(tempJPEG))
  10.                 {
  11.                     myStore.DeleteFile(tempJPEG);
  12.                 }
  13.                 IsolatedStorageFileStream myFileStream = myStore.CreateFile(tempJPEG);
  14.                 // Create a stream out of the sample JPEG file.
  15.                 // Instead of MyQuickApp in the URI, use the correct project name.
  16.                 // The use of TempJPEG was established earlier.
  17.                 Uri uri = new Uri("MyQuickApp;component/TempJPEG.jpg", UriKind.Relative);
  18.                 // Create a new WriteableBitmap object and set it to the JPEG stream.
  19.                 WriteableBitmap wb = new WriteableBitmap(bmp);
  20.                 // Encode WriteableBitmap object to a JPEG stream.
  21.                 // SaveJpeg(WriteableBitmap bitmap, Stream targetStream, int targetWidth,
  22.                 // int targetHeight, int orientation, int quality)
  23.                 Extensions.SaveJpeg(wb, myFileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
  24.                 myFileStream.Close();
  25.                 // Create a new stream from isolated storage, and save the JPEG file to
  26.                 // the media library on Windows Phone.
  27.                 myFileStream = myStore.OpenFile(tempJPEG, FileMode.Open, FileAccess.Read);
  28.                 MediaLibrary library = new MediaLibrary();
  29.                 Picture pic = library.SavePicture("SavedPicture.jpg", myFileStream);
  30.                 myFileStream.Close();
  31.                 savePhotoButton.IsEnabled = false;
  32.                 statusText.Text = "Saved!";
  33.             }
  34.             catch (Exception myError)
  35.             {
  36.                 statusText.Text = myError.Message;
  37.             }
  38.         }

Visual Basic

Code Snippet
  1. Private Sub savePhotoButton_Click(sender As Object, e As RoutedEventArgs)
  2.     Try
  3.         ' Create a filename for JPEG file in isolated storage.
  4.         Dim tempJPEG As [String] = "TempJPEG"
  5.         ' Create virtual store and file stream. Check for duplicate tempJPEG files.
  6.         Dim myStore = IsolatedStorageFile.GetUserStoreForApplication()
  7.         If myStore.FileExists(tempJPEG) Then
  8.             myStore.DeleteFile(tempJPEG)
  9.         End If
  10.         Dim myFileStream As IsolatedStorageFileStream = myStore.CreateFile(tempJPEG)
  11.         ' Create a stream out of the sample JPEG file.
  12.         ' Instead of MyQuickApp in the URI, use the correct project name.
  13.         ' The use of TempJPEG was established earlier.
  14.         Dim uri As New Uri("MyQuickApp;component/TempJPEG.jpg", UriKind.Relative)
  15.         ' Create a new WriteableBitmap object and set it to the JPEG stream.
  16.         Dim wb As New WriteableBitmap(bmp)
  17.         ' Encode WriteableBitmap object to a JPEG stream.
  18.         ' SaveJpeg(WriteableBitmap bitmap, Stream targetStream, int targetWidth,
  19.         ' int targetHeight, int orientation, int quality)
  20.         Extensions.SaveJpeg(wb, myFileStream, wb.PixelWidth, wb.PixelHeight, 0, 85)
  21.         myFileStream.Close()
  22.         ' Create a new stream from isolated storage, and save the JPEG file to
  23.         ' the media library on Windows Phone.
  24.         myFileStream = myStore.OpenFile(tempJPEG, FileMode.Open, FileAccess.Read)
  25.         Dim library As New MediaLibrary()
  26.         Dim pic As Picture = library.SavePicture("SavedPicture.jpg", myFileStream)
  27.         myFileStream.Close()
  28.         savePhotoButton.IsEnabled = False
  29.         statusText.Text = "Saved!"
  30.     Catch myError As Exception
  31.         statusText.Text = myError.Message
  32.     End Try
  33. End Sub

Le tutoriel est maintenant terminé, et vous avez un exemple de programme qui gère les entrées de la caméra, lit et écrit dans la photothèque. N'oubliez pas de débrancher le téléphone du logiciel Zune de sorte que les méthodes de démarrage des Choosers puissent fonctionner.

Voir aussi


Skip to main content