In Android you can get a description of the properties of a Camera
by retrieving a CameraInfo
. I'm interested in orientation, as described at http://developer.android.com/reference/android/hardware/Camera.CameraInfo.html#orientation
However the documentation seems inconsistent with how all four of my devices behave, and, I have news of a fifth device for which this seemly fixed value changes.
In particular, the documentation says:
The value is the angle that the camera image needs to be rotated
clockwise so it shows correctly on the display in its natural
orientation. ... For example, suppose a device has a naturally tall
screen. The back-facing camera sensor is mounted in landscape. You are
looking at the screen. If the top side of the camera sensor is aligned
with the right edge of the screen in natural orientation, the value
should be 90. If the top side of a front-facing camera sensor is
aligned with the right of the screen, the value should be 270.
But in the stated example, it is the camera image that is rotated 90 degrees clockwise relative to the naturally tall orientation, not the other way around. That is, the image, whose top is aligned with the right hand side of the device, needs 270 degrees clockwise rotation to align with the device's top side.
At least, all four of my devices report "90" for this value, and all act as if the camera's top is the right side of the device when held in natural orientation. That is, the image must be rotated 270 degrees clockwise, not 90, to match the natural orientation. The example seems correct; the first line does not.
This example code seems to support my conclusion as it only gives the right result when orientation is interpreted as above.
Strangely, I have log evidence from one user's device that shows it reporting this value as 90 at times, and 0 at other times! It ought to be a physical property of how the camera is seated in the device, right?
- Can anyone confirm that the first line of the documentation is in fact wrong, and the example is right?
- Has anyone observed a changing value of
CameraInfo.orientation
? Is there evidence in docs that this is legal behavior, or is it likely a bug in the device?
- Any other related comments, experiences, gotchas I have not run into yet?
1) Can anyone confirm that the first line of the documentation is in fact
wrong, and the example is right?
You have thoroughly addressed this already within your answer, thanks for the follow up explanation!
2) Has anyone observed a changing value of CameraInfo.orientation? Is there evidence in docs that this is legal behavior, or is it likely a
bug in the device?
While I can easily imagine this to be a bug in principle, it would still be a pretty severe one affecting all sorts of imaging related apps due to the resulting information being embedded via EXIF in photos for example (other EXIF related bugs aside for a moment).
Thus, I'd consider it more likely to be an actual feature of one of those thousands of Android devices out there, i.e. a camera with an option to physically rotate the lens. While I'm not aware of an Android based one currently, there used to be such phones available, e.g. the LG VX7000 (~2004) or the Samsung SCH-a930 (~2006) (see e.g. Rotating Camera Lens within the manual), so I'd not be surprised if something like this would appear in the Android sphere as well.
Incidentally, there is an unanswered question Why are my pics upside down or backwards. within Customer Questions & Answers for Samsung SCH-A930 regarding the latter:
Lately my pics have been upside down or backwards. Why is this
happening and how can I fix it.
This might actually be a bug in the otherwise functioning rotation adjustment hardware/firmware ;)
So in conclusion, I think it might be best to actually prepare for the orientation being able to change until you have more definite evidence for this to be a buggy device indeed.
I believe I've answered my own question here after some more thinking.
The example is correct. And, the text is correct actually. In the given example, if the preview data is displayed on the screen, it will appear rotated 90 degrees counter-clockwise, since "up" in the data is at the display's right hand, and it is shown on the display, whose "up" is at the data's left hand so to speak. So, it would be necessary to compensate by rotating the image data 90 degrees clockwise before displaying.
I think it's more natural to understand this figure as the rotation at which the camera is mounted relative to the natural orientation.
For this reasons and others I've concluded that the device that shows a changing value for orientation is simply buggy. At the least, when it reports 0, its data is acting like "90" is the right value.
Another way to deal with the problem is to extends OrientationEventListener
and override the method onOrientationChanged you will get the orientation of your phone even the autorotate disabled(because the listener emit the rotate event via sensor).
you should enable and disable the orientation listener on onResume/onPause to prevent some drain battery.
private class OnOrientationChange extends OrientationEventListener {
private boolean isEnabled = false;
public OnOrientationChange(Context context) {
super(context);
disable();
}
@Override
public void onOrientationChanged(int orientation) {
if (camera != null && orientation != ORIENTATION_UNKNOWN) {
int newOutputOrientation = getCameraPictureRotation(orientation);
if (newOutputOrientation != outputOrientation) {
outputOrientation = newOutputOrientation;
Camera.Parameters params = camera.getParameters();
params.setRotation(outputOrientation);
try {
camera.setParameters(params);
lastPictureOrientation = outputOrientation;
} catch (Exception e) {
Log.e(getClass().getSimpleName(),
"Exception updating camera parameters in orientation change",
e);
// TODO: get this info out to hosting app
}
}
}
}
@Override
public void enable() {
isEnabled = true;
super.enable();
}
@Override
public void disable() {
isEnabled = false;
super.disable();
}
boolean isEnabled() {
return (isEnabled);
}
}
thanks for common-sware for the solution