camera API rotates image based on EXIF data
Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/commit/e4cc4c5e Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/tree/e4cc4c5e Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/diff/e4cc4c5e Branch: refs/heads/master Commit: e4cc4c5eb1748845e37daf5972f8b539d56f5a56 Parents: f2703aa Author: Jesse MacFadyen <[email protected]> Authored: Wed Jun 20 15:39:01 2012 -0700 Committer: Jesse MacFadyen <[email protected]> Committed: Wed Jun 20 15:39:01 2012 -0700 ---------------------------------------------------------------------- framework/Cordova/Commands/Camera.cs | 102 +++++++++++++++++++++++++++- 1 files changed, 98 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/e4cc4c5e/framework/Cordova/Commands/Camera.cs ---------------------------------------------------------------------- diff --git a/framework/Cordova/Commands/Camera.cs b/framework/Cordova/Commands/Camera.cs index e82b72a..319744e 100644 --- a/framework/Cordova/Commands/Camera.cs +++ b/framework/Cordova/Commands/Camera.cs @@ -28,6 +28,8 @@ using System.IO; using System.IO.IsolatedStorage; using System.Windows.Media.Imaging; using Microsoft.Phone; +using Microsoft.Xna.Framework.Media; +using System.Diagnostics; namespace WP7CordovaClassLib.Cordova.Commands { @@ -171,7 +173,7 @@ namespace WP7CordovaClassLib.Cordova.Commands if (cameraOptions.PictureSourceType == CAMERA) { cameraTask = new CameraCaptureTask(); - cameraTask.Completed += onTaskCompleted; + cameraTask.Completed += onCameraTaskCompleted; cameraTask.Show(); } else @@ -179,7 +181,7 @@ namespace WP7CordovaClassLib.Cordova.Commands if ((cameraOptions.PictureSourceType == PHOTOLIBRARY) || (cameraOptions.PictureSourceType == SAVEDPHOTOALBUM)) { photoChooserTask = new PhotoChooserTask(); - photoChooserTask.Completed += onTaskCompleted; + photoChooserTask.Completed += onPickerTaskCompleted; photoChooserTask.Show(); } else @@ -190,7 +192,98 @@ namespace WP7CordovaClassLib.Cordova.Commands } - public void onTaskCompleted(object sender, PhotoResult e) + public void onCameraTaskCompleted(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)); + // Save image in media library + MediaLibrary library = new MediaLibrary(); + Picture pict = library.SavePicture(e.OriginalFileName, e.ChosenPhoto); + Debug.WriteLine("Picture image width = " + pict.Width.ToString()); + + int orient = ImageExifHelper.getImageOrientationFromStream(e.ChosenPhoto); + int newAngle = 0; + switch (orient) + { + case ImageExifOrientation.LandscapeLeft: + newAngle = 90; + break; + case ImageExifOrientation.PortraitUpsideDown: + newAngle = 180; + break; + case ImageExifOrientation.LandscapeRight: + newAngle = 270; + break; + case ImageExifOrientation.Portrait: + default: break; // 0 default already set + } + + Stream rotImageStream = ImageExifHelper.RotateStream(e.ChosenPhoto, newAngle); + + // we should return stream position back after saving stream to media library + rotImageStream.Seek(0, SeekOrigin.Begin); + + WriteableBitmap image = PictureDecoder.DecodeJpeg(rotImageStream); + + //byte[] imageBytes = new byte[rotImageStream.Length]; + //rotImageStream.Read(imageBytes, 0, imageBytes.Length); + //rotImageStream.Dispose(); + //imageBytes = null; + + imagePathOrContent = this.SaveImageToLocalStorage(image, Path.GetFileName(e.OriginalFileName)); + + + + + + } + else if (cameraOptions.DestinationType == DATA_URL) + { + imagePathOrContent = this.GetImageContent(e.ChosenPhoto); + } + else + { + // TODO: shouldn't this happen before we launch the camera-picker? + DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType")); + return; + } + + DispatchCommandResult(new PluginResult(PluginResult.Status.OK, imagePathOrContent)); + + } + catch (Exception) + { + 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; + } + + } + + public void onPickerTaskCompleted(object sender, PhotoResult e) { if (e.Error != null) { @@ -217,7 +310,8 @@ namespace WP7CordovaClassLib.Cordova.Commands } else { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrec option: destinationType")); + // TODO: shouldn't this happen before we launch the camera-picker? + DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Incorrect option: destinationType")); return; }
