1717import android .media .MediaScannerConnection ;
1818import android .net .Uri ;
1919import android .os .AsyncTask ;
20+ import android .os .Build ;
2021import android .os .Environment ;
2122import android .provider .MediaStore ;
2223import android .provider .MediaStore .Images ;
2526
2627import com .facebook .common .logging .FLog ;
2728import com .facebook .react .bridge .GuardedAsyncTask ;
28- import com .facebook .react .bridge .JSApplicationIllegalArgumentException ;
2929import com .facebook .react .bridge .NativeModule ;
3030import com .facebook .react .bridge .Promise ;
3131import com .facebook .react .bridge .ReactApplicationContext ;
@@ -637,9 +637,7 @@ private static boolean putPlayableDuration(
637637 // Do nothing. We can't handle this, and this is usually a system problem
638638 }
639639 try {
640- int timeInMillisec =
641- Integer .parseInt (
642- retriever .extractMetadata (MediaMetadataRetriever .METADATA_KEY_DURATION ));
640+ int timeInMillisec = Integer .parseInt (retriever .extractMetadata (MediaMetadataRetriever .METADATA_KEY_DURATION ));
643641 playableDuration = timeInMillisec / 1000 ;
644642 } catch (NumberFormatException e ) {
645643 success = false ;
@@ -684,19 +682,16 @@ private static boolean putImageSize(
684682 }
685683
686684 boolean success = true ;
685+ @ Nullable AssetFileDescriptor photoDescriptor = null ;
686+
687+ /* Read height and width data from the gallery cursor columns */
687688 int width = media .getInt (widthIndex );
688689 int height = media .getInt (heightIndex );
689690
691+ /* If the columns don't contain the size information, read the media file */
690692 if (width <= 0 || height <= 0 ) {
691- @ Nullable AssetFileDescriptor photoDescriptor = null ;
692693 try {
693694 photoDescriptor = resolver .openAssetFileDescriptor (photoUri , "r" );
694- } catch (FileNotFoundException e ) {
695- success = false ;
696- FLog .e (ReactConstants .TAG , "Could not open asset file " + photoUri .toString (), e );
697- }
698-
699- if (photoDescriptor != null ) {
700695 if (isVideo ) {
701696 MediaMetadataRetriever retriever = new MediaMetadataRetriever ();
702697 try {
@@ -705,12 +700,8 @@ private static boolean putImageSize(
705700 // Do nothing. We can't handle this, and this is usually a system problem
706701 }
707702 try {
708- width =
709- Integer .parseInt (
710- retriever .extractMetadata (MediaMetadataRetriever .METADATA_KEY_VIDEO_WIDTH ));
711- height =
712- Integer .parseInt (
713- retriever .extractMetadata (MediaMetadataRetriever .METADATA_KEY_VIDEO_HEIGHT ));
703+ width = Integer .parseInt (retriever .extractMetadata (MediaMetadataRetriever .METADATA_KEY_VIDEO_WIDTH ));
704+ height = Integer .parseInt (retriever .extractMetadata (MediaMetadataRetriever .METADATA_KEY_VIDEO_HEIGHT ));
714705 } catch (NumberFormatException e ) {
715706 success = false ;
716707 FLog .e (
@@ -722,21 +713,45 @@ private static boolean putImageSize(
722713 retriever .release ();
723714 } else {
724715 BitmapFactory .Options options = new BitmapFactory .Options ();
725- // Set inJustDecodeBounds to true so we don't actually load the Bitmap, but only get its
726- // dimensions instead.
716+ // Set inJustDecodeBounds to true so we don't actually load the Bitmap in memory,
717+ // but only get its dimensions
727718 options .inJustDecodeBounds = true ;
728719 BitmapFactory .decodeFileDescriptor (photoDescriptor .getFileDescriptor (), null , options );
729720 width = options .outWidth ;
730721 height = options .outHeight ;
731722 }
723+ } catch (FileNotFoundException e ) {
724+ success = false ;
725+ FLog .e (ReactConstants .TAG , "Could not open asset file " + photoUri .toString (), e );
726+ }
727+ }
732728
733- try {
734- photoDescriptor .close ();
735- } catch (IOException e ) {
736- // Do nothing. We can't handle this, and this is usually a system problem
729+ /* Read the EXIF photo data to update height and width in case a rotation is encoded */
730+ if (success && !isVideo && Build .VERSION .SDK_INT >= Build .VERSION_CODES .N ) {
731+ try {
732+ if (photoDescriptor == null ) photoDescriptor = resolver .openAssetFileDescriptor (photoUri , "r" );
733+ ExifInterface exif = new ExifInterface (photoDescriptor .getFileDescriptor ());
734+ int rotation = exif .getAttributeInt (ExifInterface .TAG_ORIENTATION , ExifInterface .ORIENTATION_NORMAL );
735+ if (rotation == ExifInterface .ORIENTATION_ROTATE_90 || rotation == ExifInterface .ORIENTATION_ROTATE_270 ) {
736+ // swap values
737+ int temp = width ;
738+ width = height ;
739+ height = temp ;
737740 }
741+ } catch (FileNotFoundException e ) {
742+ success = false ;
743+ FLog .e (ReactConstants .TAG , "Could not open asset file " + photoUri .toString (), e );
744+ } catch (IOException e ) {
745+ FLog .e (ReactConstants .TAG , "Could not get exif data for file " + photoUri .toString (), e );
738746 }
747+ }
739748
749+ if (photoDescriptor != null ) {
750+ try {
751+ photoDescriptor .close ();
752+ } catch (IOException e ) {
753+ // Do nothing. We can't handle this, and this is usually a system problem
754+ }
740755 }
741756
742757 image .putInt ("width" , width );
0 commit comments