Lessons Learnt Using the Windows Phone Camera API : Part 2

A few months ago I wrote a post about some of the stuff I learnt working with the Windows Phone camera API for Foundbite, here’s some more I’ve learnt since….

Disable Camera Buttons

Initiating a photo capture can sometimes take a bit of time, especially if you’re focusing as well, and I found even if you give the user some loading feedback it’s quite likely they might try to press the button more than once. If they do this the phone will try to initiate another camera capture which will most likely throw an InvalidOperationException. In Foundbite, after suffering from many of these exceptions, I’m disabling the on screen button and the physical camera button when the capturing process is occurring.

Dispose the Camera

You may have noticed that if you don’t dispose an instance of the PhotoCaptureDevice whenever you leave the camera page it’ll cause a whole host of problems, including giving a nasty bug where the camera feed goes green- often needing a phone restart to right itself.

In the OnNavigatedTo event on the camera page I declare a new instance of the camera and in the OnNavigatedFrom I .Dispose() the PhotoCaptureDevice which has stopped this from occurring completely.

Don’t Assume All Phones Have the Same Resolutions

It’s best to assume that every phone has different resolutions available to avoid any unexpected problems when setting the resolution. I was initialising the camera in Foundbite using the 640 x 480 resolution which I though every phone would have as the minimum. However, it seems the new Nokia Lumia 1020 doesn’t have this low resolution so was causing a crash for that particular device.

I have an idea of what kind of size image I want so I just use this fairly schoolboy method to select the closest available resolution using the widths available and the desired width:

public static int GetNearestSizeIndex(List<int> widths, int wantedSize)
{
int distanceAway = int.MaxValue;
int index = 0;
for (int i = 0; i < widths.Count; i++)
{
int distance = Math.Abs(widths[i] – wantedSize);
if (distance < distanceAway)
{
distanceAway = distance;
index = i;
}
}
return index;

As I said, pretty basic but in Foundbite I’ve had to limit the size of images to improve image size and upload speed, so this is helpful for selecting the best resolution.

Focus Illumination Mode

The FocusIlluminationMode is the small flash you sometimes see when focusing the camera. I wasn’t aware you could even control this to start off with but to stop annoying your users its best to give them an option to turn this off if they so wish (or keep it on all the time).

Make sure you check that the phone has a flash before allowing the user to manipulate the illumination mode as a Nokia Lumia 520 only has one FocusilluminationMode (off) as it has no flash.

if(camera.IsFlashAvailable()) camera.SetIlluminationMode(Settings.FocusMode.Value);

Which uses these two methods:

public void SetIlluminationMode(FocusIlluminationMode mode)
{
Device.SetProperty(KnownCameraPhotoProperties.FocusIlluminationMode, mode);
}

public bool IsFlashAvailable()
{
return (GetAvailableFlashStates().ToList().Count() > 1);
}

For more help using the camera I found this Camera Explorer sample from Nokia amazingly useful……

Advertisements

Lessons Learnt Using the Windows Phone Camera API

I’ve been working with the Windows Phone camera API (PhotoCaptureDevice) a lot recently for Foundbite, some of the things I’ve learnt:

Not every Windows Phone has flash

I didn’t realise this until recently when testing with the cheap as chips Nokia Lumia 520. It’s a great device for the price but you need to add a check to your camera code to make sure other flash modes are available before manipulating it.

Here’s a method to get the available flash states and another to check if flash is available for the current device (ie: if there is one or less flash states).

public bool IsFlashAvailable()
{
List<FlashState> flashStates = GetAvailableFlashStates().ToList();
return (flashStates.Count > 1);
}

public IReadOnlyList<FlashState> GetAvailableFlashStates()
{
IReadOnlyList<object> rawValueList = PhotoCaptureDevice.GetSupportedPropertyValues(Device.SensorLocation, KnownCameraPhotoProperties.FlashMode);
List<FlashState> flashStates = new List<FlashState>(rawValueList.Count);foreach (object rawValue in rawValueList) flashStates.Add((FlashState)(uint)rawValue);
return flashStates.AsReadOnly();
}

Update #1: Jay Benett ponts out that this can be done in a far simpler way than I have using LINQ’s .Any() https://twitter.com/JayTBennett/status/370221811423670272

Update #2: Just realised this update 1 method won’t work as even if there isn’t a flash on the device there will still be FlashState.Off in the list.

Update #3:After more discussion, it turns out there is a way to do it using Jay’s method: https://twitter.com/scottisafool/status/371913405080547328. I’m going to stop updating this post now.

In some regions the camera shutter sound can’t be turned off

Foundbite allows you to take a picture at the same time as recording audio so it wouldn’t be ideal if you could hear the shutter sound in every sound clip. It is possible to turn the sound off but in some regions of the world it’s a legal necessity to have this sound on.

It’s therefore a necessity to check that you can turn the sound off before doing so:

private void disableShutterSound()
{
if (!(bool)this.Device.GetProperty(KnownCameraGeneralProperties.IsShutterSoundRequiredForRegion))
this.Device.SetProperty(KnownCameraGeneralProperties.PlayShutterSoundOnCapture, false);
}

It’s possible to turn off the flash that happens when you focus the camera

This setting is called the FocusIlluminationMode and can easily be changed, much like FlashMode, between Auto, On and Off.

Here’s the code to get the current value and change it:

public FocusIlluminationMode GetCurrentFocusIlluminatonMode()
{
return (FocusIlluminationMode)(uint)Device.GetProperty(KnownCameraPhotoProperties.FocusIlluminationMode);
}

public void SetIlluminationMode(FocusIlluminationMode mode)
{
Device.SetProperty(KnownCameraPhotoProperties.FocusIlluminationMode, mode);
}

It’s worth nothing that you should check the flash is available before changing this mode too!
Hopefully these will be helpful and save some time for others playing around with the camera.