/*
* PhoneGap is available under *either* the terms of the modified BSD license *or* the
* MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
*
* Copyright (c) 2005-2011, Nitobi Software Inc.
* Copyright (c) 2011, Microsoft Corporation
* Copyright (c) 2011, Sergey Grebnov.
* Copyright (c) 2011, Jesse MacFadyen.
*/
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Collections.Generic;
using Microsoft.Phone.Tasks;
using System.Runtime.Serialization;
using System.IO;
using System.IO.IsolatedStorage;
using System.Windows.Media.Imaging;
using Microsoft.Phone;
namespace WP7GapClassLib.PhoneGap.Commands
{
public class Camera : BaseCommand
{
///
/// Return base64 encoded string
///
private const int DATA_URL = 0;
///
/// Return file uri
///
private const int FILE_URI = 1;
///
/// Choose image from picture library
///
private const int PHOTOLIBRARY = 0;
///
/// Take picture from camera
///
private const int CAMERA = 1;
///
/// Choose image from picture library
///
private const int SAVEDPHOTOALBUM = 2;
///
/// Take a picture of type JPEG
///
private const int JPEG = 0;
///
/// Take a picture of type PNG
///
private const int PNG = 1;
///
/// Desired width of the image
///
private int targetWidth;
///
/// desired height of the image
///
private int targetHeight;
///
/// Folder to store captured images
///
private const string isoFolder = "CapturedImagesCache";
///
/// Represents captureImage action options.
///
[DataContract]
public class CameraOptions
{
///
/// Source to getPicture from.
///
[DataMember(IsRequired = false, Name = "sourceType")]
public int PictureSourceType { get; set; }
///
/// Format of image that returned from getPicture.
///
[DataMember(IsRequired = false, Name = "destinationType")]
public int DestinationType { get; set; }
///
/// Quality of saved image
///
[DataMember(IsRequired = false, Name = "quality")]
public int Quality { get; set; }
///
/// Height in pixels to scale image
///
[DataMember(IsRequired = false, Name = "targetHeight")]
public int TargetHeight { get; set; }
///
/// Width in pixels to scale image
///
[DataMember(IsRequired = false, Name = "targetWidth")]
public int TargetWidth { get; set; }
///
/// Creates options object with default parameters
///
public CameraOptions()
{
this.SetDefaultValues(new StreamingContext());
}
///
/// Initializes default values for class fields.
/// Implemented in separate method because default constructor is not invoked during deserialization.
///
///
[OnDeserializing()]
public void SetDefaultValues(StreamingContext context)
{
PictureSourceType = CAMERA;
DestinationType = DATA_URL;
Quality = 80;
TargetHeight = -1;
TargetWidth = -1;
}
}
///
/// Used to open photo library
///
PhotoChooserTask photoChooserTask;
///
/// Used to open camera application
///
CameraCaptureTask cameraTask;
///
/// Camera options
///
CameraOptions cameraOptions;
public void getPicture(string options)
{
try
{
this.cameraOptions = String.IsNullOrEmpty(options) ?
new CameraOptions() : JSON.JsonHelper.Deserialize(options);
}
catch (Exception ex)
{
this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
return;
}
//TODO Check if all the options are acceptable
if (cameraOptions.PictureSourceType == CAMERA)
{
cameraTask = new CameraCaptureTask();
cameraTask.Completed += onTaskCompleted;
cameraTask.Show();
}
else
{
if ((cameraOptions.PictureSourceType == PHOTOLIBRARY) || (cameraOptions.PictureSourceType == SAVEDPHOTOALBUM))
{
photoChooserTask = new PhotoChooserTask();
photoChooserTask.Completed += onTaskCompleted;
photoChooserTask.Show();
}
else
{
DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
}
}
}
public void onTaskCompleted(object sender, PhotoResult e)
{
if (e.Error != null)
{
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR));
return;
}
switch (e.TaskResult)
{
case TaskResult.OK:
try
{
string imagePathOrContent = string.Empty;
if (cameraOptions.DestinationType == FILE_URI)
{
WriteableBitmap image = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName));
}
else if (cameraOptions.DestinationType == DATA_URL)
{
imagePathOrContent = this.GetImageContent(e.ChosenPhoto);
}
else
{
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrec option: destinationType"));
return;
}
DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent));
}
catch (Exception ex)
{
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error retrieving image."));
}
break;
case TaskResult.Cancel:
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection cancelled."));
break;
default:
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Selection did not complete!"));
break;
}
}
///
/// Returns image content in a form of base64 string
///
/// Image stream
/// Base64 representation of the image
private string GetImageContent(Stream stream)
{
int streamLength = (int)stream.Length;
byte[] fileData = new byte[streamLength + 1];
stream.Read(fileData, 0, streamLength);
stream.Close();
return Convert.ToBase64String(fileData);
}
///
/// Saves captured image in isolated storage
///
/// image file name
/// Image path
private string SaveImageToLocalStorage(WriteableBitmap image, string imageFileName)
{
if (image == null)
{
throw new ArgumentNullException("imageBytes");
}
try
{
var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
if (!isoFile.DirectoryExists(isoFolder))
{
isoFile.CreateDirectory(isoFolder);
}
string filePath = System.IO.Path.Combine("/" + isoFolder + "/", imageFileName);
using (var stream = isoFile.CreateFile(filePath))
{
// resize image if Height and Width defined via options
if (cameraOptions.TargetHeight > 0 && cameraOptions.TargetWidth > 0)
{
image.SaveJpeg(stream, cameraOptions.TargetWidth, cameraOptions.TargetHeight, 0, cameraOptions.Quality);
}
else
{
image.SaveJpeg(stream, image.PixelWidth, image.PixelHeight, 0, cameraOptions.Quality);
}
}
return new Uri(filePath, UriKind.Relative).ToString();
}
catch (Exception e)
{
//TODO: log or do something else
throw;
}
}
}
}