From 4aaa2130af7241f128ee561cafd17a4fb560b92c Mon Sep 17 00:00:00 2001 From: Wu-cheng Li Date: Fri, 10 Sep 2010 12:48:00 -0700 Subject: Fix the wrong rotation on naturally landscape devices. The orientation of on-screen icons and thumbnails are wrong on devices that are naturally landscape in their orientation. Display.getRotation should be used to compensate. Parameters.setRotation should also be compensated by camera's orientation. Change-Id: Ia0684fcd606252c49fa2d701ab07c73f7e29b70b --- src/com/android/camera/Camera.java | 75 ++++++++++++++++++++++---------- src/com/android/camera/ImageManager.java | 24 ---------- src/com/android/camera/Util.java | 23 +++++----- 3 files changed, 64 insertions(+), 58 deletions(-) (limited to 'src/com') diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java index 26b14f96..1c5ebedd 100644 --- a/src/com/android/camera/Camera.java +++ b/src/com/android/camera/Camera.java @@ -30,6 +30,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.hardware.Camera.CameraInfo; import android.hardware.Camera.Parameters; import android.hardware.Camera.PictureCallback; import android.hardware.Camera.Size; @@ -133,8 +134,11 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, private Parameters mParameters; private Parameters mInitialParams; - private OrientationEventListener mOrientationListener; - private int mLastOrientation = 0; // No rotation (landscape) by default. + private MyOrientationEventListener mOrientationListener; + // The device orientation in degrees. Default is unknown. + private int mOrientation = OrientationEventListener.ORIENTATION_UNKNOWN; + // The orientation compensation for icons and thumbnails. + private int mOrientationCompensation = 0; private ComboPreferences mPreferences; private static final int IDLE = 1; @@ -302,24 +306,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, // Create orientation listenter. This should be done first because it // takes some time to get first orientation. - mOrientationListener = new OrientationEventListener(Camera.this) { - @Override - public void onOrientationChanged(int orientation) { - // We keep the last known orientation. So if the user - // first orient the camera then point the camera to - if (orientation != ORIENTATION_UNKNOWN) { - orientation += 90; - } - orientation = ImageManager.roundOrientation(orientation); - if (orientation != mLastOrientation) { - mLastOrientation = orientation; - if (!mIsImageCaptureIntent) { - setOrientationIndicator(mLastOrientation); - } - mHeadUpDisplay.setOrientation(mLastOrientation); - } - } - }; + mOrientationListener = new MyOrientationEventListener(Camera.this); mOrientationListener.enable(); // Initialize location sevice. @@ -789,8 +776,18 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, private void capture() { mCaptureOnlyData = null; - // Set rotation. - mParameters.setRotation(mLastOrientation); + // Set JPEG rotation to match the orientation of what users see. The + // rotation is relative to the orientation of the camera. The value + // from OrientationEventListener is relative to the natural + // orientation of the device. CameraInfo.mOrientation is the angle + // between camera orientation and natural device orientation. The + // sum of the two is the value for setRotation. + int rotation = 0; + if (mOrientation != OrientationEventListener.ORIENTATION_UNKNOWN) { + CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId]; + rotation = (mOrientation + info.mOrientation) % 360; + } + mParameters.setRotation(rotation); // Clear previous GPS location from the parameters. mParameters.removeGpsData(); @@ -1000,7 +997,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, CameraHolder.instance().getCameraInfo()); mHeadUpDisplay.initialize(this, settings.getPreferenceGroup(R.xml.camera_preferences), - getZoomRatios(), mLastOrientation); + getZoomRatios(), mOrientationCompensation); if (mParameters.isZoomSupported()) { mHeadUpDisplay.setZoomIndex(mZoomValue); mHeadUpDisplay.setZoomListener(new ZoomControllerListener() { @@ -1016,7 +1013,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, } private void attachHeadUpDisplay() { - mHeadUpDisplay.setOrientation(mLastOrientation); + mHeadUpDisplay.setOrientation(mOrientationCompensation); FrameLayout frame = (FrameLayout) findViewById(R.id.frame); mGLRootView = new GLRootView(this); mGLRootView.setContentPane(mHeadUpDisplay); @@ -1030,6 +1027,36 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, mGLRootView = null; } + public static int roundOrientation(int orientation) { + return ((orientation + 45) / 90 * 90) % 360; + } + + private class MyOrientationEventListener + extends OrientationEventListener { + public MyOrientationEventListener(Context context) { + super(context); + } + + @Override + public void onOrientationChanged(int orientation) { + // We keep the last known orientation. So if the user first orient + // the camera then point the camera to floor or sky, we still have + // the correct orientation. + if (orientation == ORIENTATION_UNKNOWN) return; + orientation = roundOrientation(orientation); + if (orientation != mOrientation) { + mOrientation = orientation; + mOrientationCompensation = orientation + + Util.getDisplayRotation(Camera.this); + + if (!mIsImageCaptureIntent) { + setOrientationIndicator(mOrientationCompensation); + } + mHeadUpDisplay.setOrientation(mOrientationCompensation); + } + } + } + private void setOrientationIndicator(int degree) { ((RotateImageView) findViewById( R.id.review_thumbnail)).setDegree(degree); diff --git a/src/com/android/camera/ImageManager.java b/src/com/android/camera/ImageManager.java index 7251af8e..76a6d1df 100644 --- a/src/com/android/camera/ImageManager.java +++ b/src/com/android/camera/ImageManager.java @@ -155,30 +155,6 @@ public class ImageManager { } } - public static int roundOrientation(int orientationInput) { - int orientation = orientationInput; - - if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) { - orientation = 0; - } - - orientation = orientation % 360; - int retVal; - if (orientation < (0 * 90) + 45) { - retVal = 0; - } else if (orientation < (1 * 90) + 45) { - retVal = 90; - } else if (orientation < (2 * 90) + 45) { - retVal = 180; - } else if (orientation < (3 * 90) + 45) { - retVal = 270; - } else { - retVal = 0; - } - - return retVal; - } - // // Stores a bitmap or a jpeg byte array to a file (using the specified // directory and filename). Also add an entry to the media store for diff --git a/src/com/android/camera/Util.java b/src/com/android/camera/Util.java index de995621..c5de1f86 100644 --- a/src/com/android/camera/Util.java +++ b/src/com/android/camera/Util.java @@ -280,21 +280,24 @@ public class Util { return x; } - public static void setCameraDisplayOrientation(Activity activity, - int cameraId, android.hardware.Camera camera) { - android.hardware.Camera.CameraInfo info = - new android.hardware.Camera.CameraInfo(); - android.hardware.Camera.getCameraInfo(cameraId, info); + public static int getDisplayRotation(Activity activity) { int rotation = activity.getWindowManager().getDefaultDisplay() .getRotation(); - int degrees = 0; switch (rotation) { - case Surface.ROTATION_0: degrees = 0; break; - case Surface.ROTATION_90: degrees = 90; break; - case Surface.ROTATION_180: degrees = 180; break; - case Surface.ROTATION_270: degrees = 270; break; + case Surface.ROTATION_0: return 0; + case Surface.ROTATION_90: return 90; + case Surface.ROTATION_180: return 180; + case Surface.ROTATION_270: return 270; } + return 0; + } + public static void setCameraDisplayOrientation(Activity activity, + int cameraId, android.hardware.Camera camera) { + android.hardware.Camera.CameraInfo info = + new android.hardware.Camera.CameraInfo(); + android.hardware.Camera.getCameraInfo(cameraId, info); + int degrees = getDisplayRotation(activity); int result = (info.mOrientation - degrees + 360) % 360; camera.setDisplayOrientation(result); } -- cgit v1.2.3