This sample is a development template that you can extend to create your own lens app. It demonstrates key points from the Lens design guidelines and provides a media viewer and customizable helper classes that control the camera. The helper classes use the advanced capture APIs, from the Windows.Phone.Media.Capture namespace, to provide optimal performance and a greater selection of camera settings. For more info, see Lenses for Windows Phone 8 and Advanced photo capture.

Important Note:

We recommend using a Windows Phone 8 device to run this sample and develop camera apps. Some API calls may not work as expected on the emulator. Review the Windows Phone SDK release notes for the latest details.

This sample demonstrates the following points from the Lens design guidelines:

  • Lens icon support for the WXGA, WVGA, and 720P resolutions.

  • Swipe from the left to view previously captured photos.

  • Support for portrait and landscape orientations.

  • Support for the hardware camera shutter button.

  • Provides icon to control the flash.

  • Support for the front camera when it’s available.

  • Displays focus brackets while focusing.

  • Only one photo is saved to the camera roll per capture.

  • Provides a delete button for photos saved exclusively in the local folder.

A major feature of lenses is the ability to provide a rich media experience. However, rich media is beyond the scope of this sample. For more info about rich media, see the Lens design guidelines and Rich media extensibility.

Build the sample

  1. Start Visual Studio Express 2012 for Windows Phone and select File > Open > Project/Solution.

  2. Go to the directory in which you unzipped the sample. Double-click the Visual Studio Express 2012 for Windows Phone solution (.sln) file.

  3. Use Build > Rebuild Solution to build the sample.

Run the sample

  • To debug the app and then run it, press F5 or use Debug > Start Debugging.

  • To run the app without debugging, press Ctrl+F5 or use Debug > Start Without Debugging.

Launch the sample from the lens picker

  1. Run the sample, as described in the previous procedure.

  2. Launch the built-in camera app: press the hardware camera shutter button or in the App list, tap Camera.

  3. Tap the lenses button in the app bar. This launches the lens picker.

  4. In the lens picker, tap the icon for the sample. This launches the sample into a viewfinder experience.

Use the sample

This sample allows you to capture photos, save photos to the camera roll, view previously captured photos, and delete photos that are only stored in the local folder. Follow these steps to use the sample.

  1. Run the sample, as described in the previous procedures.

  2. In the app bar, tap the front button to toggle between the front camera (when available) and back camera.

  3. In the app bar, tap the flash button to toggle between flash states: on, auto, and off.

  4. Tap anywhere on the viewfinder to initiate a photo capture. Note that this will only work if your phone supports focusing on a specific region in the viewfinder. See the BeginPointFocusAndCapture method for more info.

  5. Press the hardware camera shutter button half way to initiate a focus operation. Press it all the way to capture a photo.

  6. After capturing a photo, swipe from the left, across the viewfinder to slide out the media viewer.

  7. Continue swiping from the left to view photos that are saved in the app’s local folder (and not saved in the media library).

  8. Observe that a delete button appears in the app bar of the media viewer for photos that are stored exclusively in the local folder. Apps can’t delete photos from the media library, so the media viewer doesn’t display a delete button for those photos.

  9. To view the captured photos in the camera roll, tap Start, then tap photos, and finally, tap camera roll.

Extend the sample

There are a few different ways that you can make use of this sample template:

  • Incorporate a rich media viewing/editing experience: Save additional info about the capture in your app’s local folder to provide a unique in-app experience. Rich media apps that implement rich media extensibility can be launched from the Open link of the built-in picture viewer when viewing photos they’ve saved to the library.

  • Build on top of the sample: Take the sample as it is and build the functionality that makes your lens unique directly on top of it.

  • Replace the capture experience: If your app offers a significantly different capture experience, remove the capture experience from the sample (in the MainPage.xaml and MainPage.xaml.cs files) and replace it with your own UI. If your capture experience is complex, consider creating a user control that implements your capture experience. Then put an instance of that control in the MediaViewer.FooterTemplate of MainPage.xaml.

Reconfigure the camera sensor

This procedure describes how you can modify the sample to use different camera settings. For more info about the available camera settings, see Advanced capture properties.

  1. Add a setting to the CameraSettings class in CameraSettings.cs so that it can be persisted between camera load/unload cycles. Note that the camera is unloaded when the user scrolls two photos away from the viewfinder for performance and battery reasons. The user will expect the settings that they selected to still be in effect when they scroll back to the viewfinder.

  2. Add a property to the LensViewModel class that exposes the property you want to be able to configure. See the FlashState property as an example.

  3. Add a property to the CameraController class to allow callers to get/set the property. See CameraController.FlashState as an example.

  4. Add a property to the CameraEngine class to allow callers to get/set the property. See CameraEngine.FlashState as an example.

  5. Update LensViewModel.GetDefaultCameraSettings to pick a default value for the setting.

  6. Update LensViewModel.ApplyCameraSettings to set the property.

  7. Update MainPage.xaml and/or MainPage.xaml.cs to set the new property you added on LensViewModel as you see fit.

Edit the photo before saving it

Some lenses edit photos before saving them. If your app does that, keep in mind the following points:

  • Add a call to your image modification code in the LensViewModel.OnStillCaptureComplete method.

  • The OnStillCaptureComplete method provides two JPEG-encoded streams that you can edit before saving them to the camera roll: thumbnailStream and imageStream (the full resolution photo).

  • OnStillCaptureComplete runs on a background thread. This is why the Dispatcher invokes some of the work on the UI thread.

Solution overview

This solution is comprised of two projects: MediaViewer and sdkBasicLensWP8CS. The MediaViewer project contains all of the code for the media viewer control. The media viewer displays photos from the camera roll and local folder. The sdkBasicLensWP8CS project contains the code for the Basic Lens Sample. The primary helper classes in this sample are named CameraEngine, CameraControl, and WorkflowBase. See the following sections for more info about this solution and how you can extend it.

MediaViewer project

Here are a few items to note about this project:

  • MediaViewer class: A control which displays content in a page-by-page fashion similar to the built-in picture viewer. It supports an optional header and footer, and in between it renders items supplied by your app. This control also has the ability to allow users to pinch zoom when viewing items. The MediaViewer is a virtualizing control, so it loads only the data it needs, and scales to very large sets of data.

  • ThumbnailedImageViewer class: This is the default ItemTemplate for the MediaViewer control, and displays images that have an associated thumbnail. Add objects to the MediaViewer.Items collection that implement the IThumbnailedImage interface so that the ThumbnailedImageViewer can display them. For examples that implement this interface, see LocalFolderThumbnailedImage and MediaLibraryThumbnailedImage.

sdkBasicLensWP8CS project

Here are a few items to note about this project:

  • MainPage class: This page contains a MediaViewer control with a FooterTemplate that implements a photo capture experience. All presentation layer concerns are handled in the code-behind file, MainPage.xaml.cs, and the business logic is implemented in the LensViewModel class.

  • LensViewModel class: This viewmodel holds the list of items to be bound to the MediaViewer.Item collection, as well as the business logic to implement the lens. It communicates with the CameraEngine model class.

  • CameraEngine class: This class handles all of the interaction with the capture API. Most importantly, it serializes most operations to reduce corner cases that would otherwise have to be handled manually. It processes a single workflow at a time, and most of the methods on this class simply queue up a new workflow. Workflows always execute in the order they were queued (FIFO), and are strictly serialized. The CameraEngine holds a reference to the CameraController class which directly wraps the capture API. It does not expose the CameraController to its callers, reducing the chance of accidental unserialized access to the capture API.

  • WorkflowBase class: The base class for all workflows. It implements some common logic needed by all workflows.

  • CameraController class: This class encapsulates the capture API and is used by the workflows.