@@ -18,44 +18,47 @@ Licensed to the Apache Software Foundation (ASF) under one
1818*/
1919package org .apache .cordova .mediacapture ;
2020
21- import java .io .File ;
22- import java .io .FileInputStream ;
23- import java .io .IOException ;
24- import java .io .OutputStream ;
25- import java .lang .reflect .InvocationTargetException ;
26- import java .lang .reflect .Field ;
27- import java .lang .reflect .Method ;
28- import java .util .Arrays ;
29-
30- import android .os .Build ;
31- import android .os .Bundle ;
32-
33- import org .apache .cordova .file .FileUtils ;
34- import org .apache .cordova .file .LocalFilesystemURL ;
35-
36- import org .apache .cordova .CallbackContext ;
37- import org .apache .cordova .CordovaPlugin ;
38- import org .apache .cordova .LOG ;
39- import org .apache .cordova .PermissionHelper ;
40- import org .apache .cordova .PluginManager ;
41- import org .apache .cordova .mediacapture .PendingRequests .Request ;
42- import org .json .JSONArray ;
43- import org .json .JSONException ;
44- import org .json .JSONObject ;
45-
4621import android .Manifest ;
4722import android .app .Activity ;
4823import android .content .ContentResolver ;
4924import android .content .ContentValues ;
25+ import android .content .Context ;
5026import android .content .Intent ;
5127import android .content .pm .PackageManager ;
5228import android .content .pm .PackageManager .NameNotFoundException ;
5329import android .database .Cursor ;
30+ import android .graphics .Bitmap ;
5431import android .graphics .BitmapFactory ;
32+ import android .graphics .Matrix ;
5533import android .media .MediaPlayer ;
5634import android .net .Uri ;
35+ import android .os .Build ;
36+ import android .os .Bundle ;
5737import android .os .Environment ;
5838import android .provider .MediaStore ;
39+ import android .support .annotation .Nullable ;
40+ import android .support .media .ExifInterface ;
41+
42+ import org .apache .cordova .CallbackContext ;
43+ import org .apache .cordova .CordovaPlugin ;
44+ import org .apache .cordova .LOG ;
45+ import org .apache .cordova .PermissionHelper ;
46+ import org .apache .cordova .PluginManager ;
47+ import org .apache .cordova .file .FileUtils ;
48+ import org .apache .cordova .file .LocalFilesystemURL ;
49+ import org .apache .cordova .mediacapture .PendingRequests .Request ;
50+ import org .json .JSONArray ;
51+ import org .json .JSONException ;
52+ import org .json .JSONObject ;
53+
54+ import java .io .ByteArrayOutputStream ;
55+ import java .io .File ;
56+ import java .io .IOException ;
57+ import java .io .InputStream ;
58+ import java .lang .reflect .Field ;
59+ import java .lang .reflect .InvocationTargetException ;
60+ import java .lang .reflect .Method ;
61+ import java .util .Arrays ;
5962
6063public class Capture extends CordovaPlugin {
6164
@@ -183,7 +186,7 @@ else if (mimeType.equals(VIDEO_3GPP) || mimeType.equals(VIDEO_MP4)) {
183186 /**
184187 * Get the Image specific attributes
185188 *
186- * @param filePath path to the file
189+ * @param fileUrl path to the file
187190 * @param obj represents the Media File Data
188191 * @return a JSONObject that represents the Media File Data
189192 * @throws JSONException
@@ -287,6 +290,12 @@ private static void createWritableFile(File file) throws IOException {
287290 file .setWritable (true , false );
288291 }
289292
293+ private static Bitmap rotateImage (Bitmap source , float angle ) {
294+ Matrix matrix = new Matrix ();
295+ matrix .postRotate (angle );
296+ return Bitmap .createBitmap (source , 0 , 0 , source .getWidth (), source .getHeight (), matrix , true );
297+ }
298+
290299 /**
291300 * Sets up an intent to capture video. Result handled by onActivityResult()
292301 */
@@ -378,8 +387,16 @@ public void onAudioActivityResult(Request req, Intent intent) {
378387 }
379388
380389 public void onImageActivityResult (Request req ) {
390+ Uri uri = imageUri ;
391+
392+ // Check image rotation
393+ Bitmap rotatedBitmap = rotateAccordingToExifOrientation (uri );
394+ if (rotatedBitmap != null ) {
395+ uri = fromBitmapToUri (this .cordova .getContext (), rotatedBitmap );
396+ }
397+
381398 // Add image to results
382- req .results .put (createMediaFile (imageUri ));
399+ req .results .put (createMediaFile (uri ));
383400
384401 checkForDuplicateImage ();
385402
@@ -537,6 +554,51 @@ private Uri whichContentStore() {
537554 }
538555 }
539556
557+ @ Nullable
558+ private Bitmap rotateAccordingToExifOrientation (Uri uri ) {
559+ Context context = this .cordova .getContext ();
560+ int orientation ;
561+ Bitmap bitmap ;
562+ try {
563+ InputStream inputStream = context .getContentResolver ().openInputStream (uri );
564+ if (inputStream == null )
565+ throw new IOException ("input stream from ContentResolver is null" );
566+ ExifInterface ei = new ExifInterface (inputStream );
567+ orientation = ei .getAttributeInt (ExifInterface .TAG_ORIENTATION , ExifInterface .ORIENTATION_UNDEFINED );
568+ bitmap = MediaStore .Images .Media .getBitmap (context .getContentResolver (), uri );
569+ } catch (IOException e ) {
570+ LOG .e (LOG_TAG , "Failed reading bitmap" , e );
571+ return null ;
572+ }
573+
574+ Bitmap rotatedBitmap ;
575+ switch (orientation ) {
576+ case ExifInterface .ORIENTATION_ROTATE_90 :
577+ rotatedBitmap = rotateImage (bitmap , 90 );
578+ break ;
579+
580+ case ExifInterface .ORIENTATION_ROTATE_180 :
581+ rotatedBitmap = rotateImage (bitmap , 180 );
582+ break ;
583+
584+ case ExifInterface .ORIENTATION_ROTATE_270 :
585+ rotatedBitmap = rotateImage (bitmap , 270 );
586+ break ;
587+
588+ case ExifInterface .ORIENTATION_NORMAL :
589+ default :
590+ rotatedBitmap = bitmap ;
591+ }
592+ return rotatedBitmap ;
593+ }
594+
595+ private Uri fromBitmapToUri (Context context , Bitmap inImage ) {
596+ ByteArrayOutputStream bytes = new ByteArrayOutputStream ();
597+ inImage .compress (Bitmap .CompressFormat .JPEG , 85 , bytes );
598+ String path = MediaStore .Images .Media .insertImage (context .getContentResolver (), inImage , "title" , null );
599+ return Uri .parse (path );
600+ }
601+
540602 private void executeRequest (Request req ) {
541603 switch (req .action ) {
542604 case CAPTURE_AUDIO :
0 commit comments