@@ -805,6 +805,83 @@ public static double[] getIntrinsicMatrixFromExif(OpenAthenaExifInterface exif)
805
805
}
806
806
}
807
807
808
+ public static float getDigitalZoomRatio (OpenAthenaExifInterface exif ) throws Exception {
809
+ float digitalZoomRatio = 1.0f ;
810
+
811
+ String make = exif .getAttribute (ExifInterface .TAG_MAKE );
812
+ if (make == null ) make = "" ;
813
+ String model = exif .getAttribute (ExifInterface .TAG_MODEL );
814
+ if (model == null ) model = "" ;
815
+
816
+ JSONObject drone = getMatchingDrone (exif );
817
+
818
+ try {
819
+ double [] pixelDimensions = new double [4 ];
820
+ if (drone != null ) {
821
+ pixelDimensions [0 ] = (double ) rationalToFloat (drone .getString ("ccdWidthMMPerPixel" ));
822
+ pixelDimensions [1 ] = (double ) rationalToFloat (drone .getString ("ccdHeightMMPerPixel" ));
823
+ pixelDimensions [2 ] = (double ) drone .getInt ("widthPixels" );
824
+ pixelDimensions [3 ] = (double ) drone .getInt ("heightPixels" );
825
+ } else {
826
+ // placeholder values which will never be used
827
+ pixelDimensions [0 ] = -1.0d ;
828
+ pixelDimensions [1 ] = -1.0d ;
829
+ pixelDimensions [2 ] = -1.0d ;
830
+ pixelDimensions [3 ] = -1.0d ;
831
+ }
832
+ String digitalZoomRational = exif .getAttribute (ExifInterface .TAG_DIGITAL_ZOOM_RATIO );
833
+ if (digitalZoomRational != null && !digitalZoomRational .equals ("" )) {
834
+ digitalZoomRatio = rationalToFloat (exif .getAttribute (ExifInterface .TAG_DIGITAL_ZOOM_RATIO ));
835
+ if (digitalZoomRatio < 1.0f ) {
836
+ digitalZoomRatio = 1.0f ;
837
+ }
838
+ }
839
+
840
+ if (make .equalsIgnoreCase ("PARROT" )) {
841
+ if (model .equalsIgnoreCase ("ANAFI" ) || model .equalsIgnoreCase ("ANAFIUSA" ) || model .equalsIgnoreCase ("ANAFIUA" )) {
842
+ Log .d (TAG , "isThermal: " + isThermal (exif ));
843
+ if (!isThermal (exif )) {
844
+ Log .d (TAG , "getDigitalZoomRatio special case for parrot triggered" );
845
+ if (drone == null ) {
846
+ throw new Exception ("Could not find necessary data for Parrot Anafi" );
847
+ }
848
+ double imageWidth = exif .getAttributeInt (ExifInterface .TAG_IMAGE_WIDTH , -1 );
849
+ if (imageWidth <= 0.0d ) {
850
+ throw new Exception ("Could not determine width of image" );
851
+ }
852
+ // Parrot ANAFI and ANAFI USA do not report digital zoom correctly in EXIF DigitalZoomRatio tag
853
+ // as a workaround, we will look at the pixel width of the image
854
+ // and assume it is cropped if it is less than the full sensor size.
855
+ // ALTHOUGH: If a Parrot image has been scaled down by external software this value will be completely wrong
856
+ digitalZoomRatio = 5344.0f / (float ) imageWidth ;
857
+ }
858
+ }
859
+ }
860
+ if (digitalZoomRatio != 1.0f ) {
861
+ Log .d (TAG , "digitalZoomRatio is: " + digitalZoomRatio );
862
+ // Some thermal cameras perform undocumented integer upscaling on digitally zoomed thermal images
863
+ // (which seems to be atypical for images with digital zoom)
864
+ // to compensate, we ignore the digitalZoomRatio when calculating
865
+ // the number of pixels for width and height
866
+ //
867
+ // Known behavior for Autel Evo III 640T, (TODO) might affect other make/models and/or color cameras as well!
868
+ if (isThermal (exif ) && make .equalsIgnoreCase ("AUTEL ROBOTICS" )) {
869
+ Log .d (TAG , "edge case detected: image had undocumented pixel upscaling. Ignoring digitalZoomRatio" );
870
+ digitalZoomRatio = 1.0f ;
871
+ }
872
+ }
873
+ } catch (JSONException jse ) {
874
+ if (make .equalsIgnoreCase ("PARROT" )) {
875
+ if (model .equalsIgnoreCase ("ANAFI" ) || model .equalsIgnoreCase ("ANAFIUSA" ) || model .equalsIgnoreCase ("ANAFIUA" )) {
876
+ if (!isThermal (exif )) {
877
+ throw new Exception ("Could not find necessary data for Parrot Anafi" );
878
+ }
879
+ }
880
+ }
881
+ }
882
+ return digitalZoomRatio ;
883
+ }
884
+
808
885
protected static double [] getIntrinsicMatrixFromKnownCCD (OpenAthenaExifInterface exif , double [] pixelDimensions ) throws Exception {
809
886
JSONObject drone = getMatchingDrone (exif );
810
887
@@ -843,27 +920,7 @@ protected static double[] getIntrinsicMatrixFromKnownCCD(OpenAthenaExifInterface
843
920
double ccdWidthPixels = pixelDimensions [2 ];
844
921
double ccdHeightPixels = pixelDimensions [3 ];
845
922
846
- String digitalZoomRational = exif .getAttribute (ExifInterface .TAG_DIGITAL_ZOOM_RATIO );
847
- float digitalZoomRatio = 1.0f ;
848
- if (digitalZoomRational != null && !digitalZoomRational .equals ("" )) {
849
- digitalZoomRatio = rationalToFloat (exif .getAttribute (ExifInterface .TAG_DIGITAL_ZOOM_RATIO ));
850
- if (digitalZoomRatio < 1.0f ) {
851
- digitalZoomRatio = 1.0f ;
852
- }
853
- }
854
- if (digitalZoomRatio != 1.0f ) {
855
- Log .d (TAG , "digitalZoomRatio is: " + digitalZoomRatio );
856
- // Some thermal cameras perform undocumented integer upscaling on digitally zoomed thermal images
857
- // (which seems to be atypical for images with digital zoom)
858
- // to compensate, we ignore the digitalZoomRatio when calculating
859
- // the number of pixels for width and height
860
- //
861
- // Known behavior for Autel Evo III 640T, (TODO) might affect other make/models and/or color cameras as well!
862
- if (isThermal (exif ) && exif .getAttribute (ExifInterface .TAG_MAKE ).equalsIgnoreCase ("AUTEL ROBOTICS" )) {
863
- Log .d (TAG , "edge case detected: image had undocumented pixel upscaling. Ignoring digitalZoomRatio" );
864
- digitalZoomRatio = 1.0f ;
865
- }
866
- }
923
+ float digitalZoomRatio = getDigitalZoomRatio (exif );
867
924
868
925
double imageWidth = exif .getAttributeInt (ExifInterface .TAG_IMAGE_WIDTH , -1 );
869
926
double imageHeight = exif .getAttributeInt (ExifInterface .TAG_IMAGE_LENGTH , -1 ); // Image Height
@@ -904,14 +961,7 @@ protected static double[] getIntrinsicMatrixFromExif35mm(OpenAthenaExifInterface
904
961
throw new Exception (parent .getString (R .string .error_metadata_extractor_focal_length_could_not_be_determined ));
905
962
}
906
963
907
- String digitalZoomRational = exif .getAttribute (ExifInterface .TAG_DIGITAL_ZOOM_RATIO );
908
- float digitalZoomRatio = 1.0f ;
909
- if (digitalZoomRational != null && !digitalZoomRational .equals ("" )) {
910
- digitalZoomRatio = rationalToFloat (exif .getAttribute (ExifInterface .TAG_DIGITAL_ZOOM_RATIO ));
911
- if (digitalZoomRatio < 1.0f ) {
912
- digitalZoomRatio = 1.0f ;
913
- }
914
- }
964
+ float digitalZoomRatio = getDigitalZoomRatio (exif );
915
965
916
966
double imageWidth = exif .getAttributeInt (ExifInterface .TAG_IMAGE_WIDTH , 0 );
917
967
double imageHeight = exif .getAttributeInt (ExifInterface .TAG_IMAGE_LENGTH , 0 ); // Image Height
0 commit comments