diff --git a/plugin.xml b/plugin.xml
index 7b4bb87b..e035ad70 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -91,6 +91,8 @@ xmlns:rim="http://www.blackberry.com/ns/widgets"
+
+
diff --git a/src/android/Capture.java b/src/android/Capture.java
index 33c3413b..c12e5b32 100644
--- a/src/android/Capture.java
+++ b/src/android/Capture.java
@@ -18,16 +18,18 @@ Licensed to the Apache Software Foundation (ASF) under one
*/
package org.apache.cordova.mediacapture;
+import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
-import java.io.OutputStream;
+import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
@@ -53,10 +55,13 @@ Licensed to the Apache Software Foundation (ASF) under one
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
+import android.support.annotation.Nullable;
+import android.support.media.ExifInterface;
public class Capture extends CordovaPlugin {
@@ -185,7 +190,7 @@ else if (mimeType.equals(VIDEO_3GPP) || mimeType.equals(VIDEO_MP4)) {
/**
* Get the Image specific attributes
*
- * @param filePath path to the file
+ * @param fileUrl path to the file
* @param obj represents the Media File Data
* @return a JSONObject that represents the Media File Data
* @throws JSONException
@@ -260,7 +265,7 @@ private void captureImage(Request req) {
!PermissionHelper.hasPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
boolean needCameraPermission = cameraPermissionInManifest &&
- !PermissionHelper.hasPermission(this, Manifest.permission.CAMERA);
+ !PermissionHelper.hasPermission(this, Manifest.permission.CAMERA);
if (needExternalStoragePermission || needCameraPermission) {
if (needExternalStoragePermission && needCameraPermission) {
@@ -293,6 +298,12 @@ private static void createWritableFile(File file) throws IOException {
file.setWritable(true, false);
}
+ private static Bitmap rotateImage(Bitmap source, float angle) {
+ Matrix matrix = new Matrix();
+ matrix.postRotate(angle);
+ return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
+ }
+
/**
* Sets up an intent to capture video. Result handled by onActivityResult()
*/
@@ -384,8 +395,16 @@ public void onAudioActivityResult(Request req, Intent intent) {
}
public void onImageActivityResult(Request req) {
+ Uri uri = imageUri;
+
+ // Check image rotation
+ Bitmap rotatedBitmap = rotateAccordingToExifOrientation(uri);
+ if (rotatedBitmap != null) {
+ uri = fromBitmapToUri(this.cordova.getContext(), rotatedBitmap);
+ }
+
// Add image to results
- req.results.put(createMediaFile(imageUri));
+ req.results.put(createMediaFile(uri));
checkForDuplicateImage();
@@ -506,11 +525,11 @@ private JSONObject createErrorObject(int code, String message) {
*/
private Cursor queryImgDB(Uri contentStore) {
return this.cordova.getActivity().getContentResolver().query(
- contentStore,
- new String[] { MediaStore.Images.Media._ID },
- null,
- null,
- null);
+ contentStore,
+ new String[] { MediaStore.Images.Media._ID },
+ null,
+ null,
+ null);
}
/**
@@ -543,6 +562,52 @@ private Uri whichContentStore() {
}
}
+ @Nullable
+ private Bitmap rotateAccordingToExifOrientation(Uri uri) {
+ Context context = this.cordova.getContext();
+ int orientation;
+ Bitmap bitmap;
+ try {
+ InputStream inputStream = context.getContentResolver().openInputStream(uri);
+ if (inputStream == null)
+ throw new IOException("input stream from ContentResolver is null");
+ ExifInterface ei = new ExifInterface(inputStream);
+ orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
+ bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), uri);
+ } catch (IOException e) {
+ LOG.e(LOG_TAG, "Failed reading bitmap", e);
+ return null;
+ }
+
+ Bitmap rotatedBitmap;
+ switch (orientation) {
+ case ExifInterface.ORIENTATION_ROTATE_90:
+ rotatedBitmap = rotateImage(bitmap, 90);
+ break;
+
+ case ExifInterface.ORIENTATION_ROTATE_180:
+ rotatedBitmap = rotateImage(bitmap, 180);
+ break;
+
+ case ExifInterface.ORIENTATION_ROTATE_270:
+ rotatedBitmap = rotateImage(bitmap, 270);
+ break;
+
+ case ExifInterface.ORIENTATION_NORMAL:
+ default:
+ // use original bitmap
+ rotatedBitmap = null;
+ }
+ return rotatedBitmap;
+ }
+
+ private Uri fromBitmapToUri(Context context, Bitmap inImage) {
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
+ String path = MediaStore.Images.Media.insertImage(context.getContentResolver(), inImage, "title", null);
+ return Uri.parse(path);
+ }
+
private void executeRequest(Request req) {
switch (req.action) {
case CAPTURE_AUDIO: