Background: I am writing a camera app for a messenger program. I cannot save the captured image to persistent disk at any time. The camera must support all orientations. My implementation is that of the familiar Surfaceview examples. I use the Display class to detect orientation and rotate the camera accordingly. In the takePicture jpeg callback, I construct a bitmap from the byte in order to get around some aspect ratio issues I was having: android camera API cross device nightmare
Problem Description: On some devices, the constructed Bitmap taken at ROTATION_270 (device rotated 90 degrees clockwise) comes in upside down. So far, it seems to be Samsung. I can only assume that maybe the camera is soldered on the other way or something to that affect but that's neither here nor there. While I can check if a Bitmap is sideways I can't logically check if it is upside down by dimensions so I need access to the EXIF data.
Android provides a parser for this http://developer.android.com/reference/android/media/ExifInterface.html but unfortunately it has a single constructor which accepts a file... which I don't have and don't want. Intuitively I could write a constructor for a byte array but that seems really painful given their calls into native code http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2.1_r1/android/media/ExifInterface.java
My question then has two parts:
NOTE newer versions of metadata-extractor work directly on Android without modification, and are available via Maven.
The bad news:
Android Api sadly won't allow you to read exif data from a
Stream, only from a
ExifInterface don't have a constructor with an
So you must parse jpeg content by yourself.
The good news:
Api exists in pure java for this. You can use this one: http://www.drewnoakes.com/code/exif/
It's Open Source and published under Apache Licence 2. Download it and save it in your /libs folder.
There is a constructor with an
public ExifReader(java.io.InputStream is)
You can build an
InputStream backed by your
byte using a
ByteArrayInputStream like this:
InputStream is = new ByteArrayInputStream(decodedBytes);