Android Question Device orientation, snapshot rotation, oh my!

canalrun

Well-Known Member
Licensed User
Longtime User
Hello,
I wish I had a dollar for every time I've addressed this issue in the last few years – I would be a rich guy :).

I have an app that allows a snapshot to be taken from the camera and the image displayed within the app. I use the intent from NJDude (Thanks NJDude):
https://www.b4x.com/android/forum/t...ack-from-camera-app-intent.11378/#post-132920

This intent returns a JPEG file, using the filename passed.

The image is rotated depending on the orientation (portrait/landscape) of my app and the orientation of the device when the snapshot was taken.

With my app in portrait and the snapshot taken in portrait, I find I have to rotate the image within the return file 90° to display it properly in my app. If the app is in portrait, but the snapshot image was taken holding the device in landscape, I don't have to rotate the image 90°.

In both cases the width and height of the image reported is the same. The difference is in the actual orientation of the image within the file.

I think there are two things going on here: 1) There is the device rotation. 2) And there is the image rotation. This may be stored as part of the image, maybe as Exif information, and describes the camera orientation when the picture was taken.

Erel has previously posted some code to determine the device rotation. Is there a way to get the image rotation information? I am thinking one needs to use a combination of both to properly display an image file.

Is there a way to get the image rotation information as part of the return from the intent? Another way?

Am I still barking up the wrong tree?

Thanks,
Barry.
 

canalrun

Well-Known Member
Licensed User
Longtime User
Once again I think I may finally have it :D.

I use the get device rotation code from Erel:
B4X:
Sub GetRotation As Int
  Dim r As Reflector

  r.Target = r.GetContext
  r.Target = r.RunMethod2("getSystemService", "window", "java.lang.String")
  r.Target = r.RunMethod("getDefaultDisplay")

  Return r.RunMethod("getRotation")
End Sub

And bitmap rotation code also from Erel:
B4X:
Sub RotateImage(obmp As Bitmap, degree As Float) As Bitmap
   Dim matrix As JavaObject
 
   matrix.InitializeNewInstance("android.graphics.Matrix", Null)
   matrix.RunMethod("postRotate", Array(degree))
 
   Dim bmp As JavaObject
 
   bmp.InitializeStatic("android.graphics.Bitmap")
 
   Dim NewImage As Bitmap = _
     bmp.RunMethod("createBitmap", Array(obmp, 0, 0, obmp.Width, obmp.Height, matrix, True))
   
   Return NewImage
End Sub

The JpegUtils library from agraham:
https://www.b4x.com/android/forum/threads/jpegutils-library-gives-access-to-exif-data.11629/

And the camera "take picture" intent code from NJDude (it saves a JPEG file):
https://www.b4x.com/android/forum/t...ack-from-camera-app-intent.11378/#post-132920

I get the device rotation and the exif orientation from the JPEG file returned from the take picture intent.

According to the diagram on this page (orientation of F's based on exif)
http://sylvana.net/jpegcrop/exif_orientation.html

I can rotate the image as necessary knowing my device orientation and the reported exif orientation. For example if my device orientation is portrait and exif reported orientation is 6, then I have to rotate 90°.

Woo hoo!

Barry.
 
Upvote 0
Top