The camera service allows a developer to use the PhotoCamera class in an MVVM manner

Available for
WPF / Silverlight / WP7 / WP7 Mango

Test/Emulation service available: yes

There is also an article availble about this service: WP7 Mango and Unit Testing the Camera

Starting and stopping the service
The PhotoCamera documentation continuously states that the camera object must be created and disposed properly. In the service, this is encapsulated by the StartService and StopService methods. To start the service, use the code below:

var cameraService = GetService<ICameraService>();
cameraService.CaptureThumbnailAvailable += OnCameraServiceCaptureThumbnailAvailable;
cameraService.CaptureImageAvailable += OnCameraServiceCaptureImageAvailable;
cameraService.Start();

To stop the service, use the code below: (note: the Close method is feature of Catel):

protected override void Close()
{
    var cameraService = GetService<ICameraService>();
    cameraService.Stop();
    cameraService.CaptureThumbnailAvailable -= OnCameraServiceCaptureThumbnailAvailable;
    cameraService.CaptureImageAvailable -= OnCameraServiceCaptureImageAvailable;
}

Capturing images
To capture images, several things must be done. The first action to accomplish is to subscribe to the ICameraService.CaptureImageAvailable event. The next step is to invoke the CaptureImage method like shown below:

CameraService.CaptureImage();

The last part is very important. You will need to read the image stream from the CaptureImageAvailable event:

BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(e.ImageStream);

Showing a video of camera in a view
To show a preview of the camera input on the phone, first subscribe to the ICameraService.CaptureThumbnailImageAvailable event. Next step is to create a property on the view model:

/// <summary>
/// Gets or sets the current photo.
/// </summary>
public BitmapImage CurrentPhoto
{
    get { return GetValue<BitmapImage>(CurrentPhotoProperty); }
    set { SetValue(CurrentPhotoProperty, value); }
}

/// <summary>
/// Register the CurrentPhoto property so it is known in the class.
/// </summary>
public static readonly PropertyData CurrentPhotoProperty = RegisterProperty("CurrentPhoto", typeof(BitmapImage));

This property definition is a Catel property, but if you prefer using a different MVVM framework or your own property definition style, you are free to do that as well.
In the view, use the Image control to show the current photo:

<Image Grid.Row="0" Source="{Binding CurrentPhoto}" />

Last but not least, we need to update the CurrentPhoto property when a new thumbnail is available.

private void OnCameraServiceCaptureThumbnailAvailable(object sender, ContentReadyEventArgs e)
{
    BitmapImage bitmap = new BitmapImage();
    bitmap.SetSource(e.ImageStream);
    CurrentPhoto = bitmap;
}

Instantiating the test implementation
The test implementation of the CameraService needs to be instantiated with an image. The service will use this image to create an animation. The animation that will be applied is the image scrolling to the right pixel by pixel.

To instantiate the test service, add an image to the Windows Phone 7 project and set its build action to Resource. Then instantiate the service like in the code below:

var testImage = new BitmapImage();
var streamResourceInfo = Application.GetResourceStream(new Uri("/MyAssembly;component/Resources/Images/MyImage.png", UriKind.RelativeOrAbsolute));
testImage.CreateOptions = BitmapCreateOptions.None;
testImage.SetSource(streamResourceInfo.Stream);
_testCameraService = new CameraService(testImage);
serviceLocator.RegisterInstance<ICameraService>(_testCameraService);

By default, the CameraService will generate a new thumbnail image every 50 milliseconds. It is possible to customize this with a constructor overload.

Customizing camera settings for testing
Sometimes it is required to test different resolutions. One way to do this is to buy all available Windows Phone 7 devices and test the software on all the cameras. An easier way is to use the ICameraService and customize the camera options to test how the application responds to the different settings.

The settings are stored in the CameraServiceTestData class. This class allows customizing all the properties normally found on the PhotoCamera class. For example, to only allow the primary camera (because front facing cameras are not supported by all devices), use the following code:

var cameraTestSettings = new CameraServiceTestData();
cameraTestSettings.SupportedCameraTypes = CameraType.Primary;
cameraService.UpdateTestData(cameraTestSettings);

It is also possible to change the thumbnail and final resolution of the images:

var cameraTestSettings = new CameraServiceTestData();
cameraTestSettings.PreviewResolution = new Size(400, 800);
cameraTestSettings.Resolution = new Size(1200, 2400);
cameraService.UpdateTestData(cameraTestSettings);

Last edited Sep 3, 2011 at 10:45 AM by GeertvanHorrik, version 5

Comments

No comments yet.