summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSol Boucher <solb@google.com>2014-08-16 00:23:44 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-08-15 18:56:10 +0000
commit182acbc3f78ea6c6edd6bd5d67c62188b4079243 (patch)
tree104c47d30b9f50f88ad9a14a54252a8d1583d23c
parentb2df32dd892ae8076714b7ebd33c715378c4c730 (diff)
parentf9feab9a826e5b33d811e757bdfdbfa0738fcfa5 (diff)
downloadandroid_frameworks_ex-182acbc3f78ea6c6edd6bd5d67c62188b4079243.tar.gz
android_frameworks_ex-182acbc3f78ea6c6edd6bd5d67c62188b4079243.tar.bz2
android_frameworks_ex-182acbc3f78ea6c6edd6bd5d67c62188b4079243.zip
Merge "camera2-portability: Provide preview transformation matrix" into lmp-dev
-rw-r--r--camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java43
-rw-r--r--camera2/portability/src/com/android/ex/camera2/portability/CameraDeviceInfo.java91
2 files changed, 118 insertions, 16 deletions
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java
index fc19aed..e675796 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/AndroidCamera2AgentImpl.java
@@ -19,7 +19,9 @@ package com.android.ex.camera2.portability;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.ImageFormat;
+import android.graphics.Matrix;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
@@ -460,7 +462,6 @@ class AndroidCamera2AgentImpl extends CameraAgent {
}*/
case CameraActions.SET_DISPLAY_ORIENTATION: {
- // TODO: Need to handle preview in addition to capture
// Only set the JPEG capture orientation if requested to do so; otherwise,
// capture in the sensor's physical orientation
mPersistentSettings.set(CaptureRequest.JPEG_ORIENTATION, msg.arg2 > 0 ?
@@ -1144,11 +1145,51 @@ class AndroidCamera2AgentImpl extends CameraAgent {
}
@Override
+ public Matrix getPreviewTransform(int currentDisplayOrientation,
+ RectF surfaceDimensions,
+ RectF desiredBounds) {
+ if (!orientationIsValid(currentDisplayOrientation)) {
+ return new Matrix();
+ }
+
+ // The system transparently transforms the image to fill the surface
+ // when the device is in its natural orientation. We rotate the
+ // coordinates of the rectangle's corners to be relative to the
+ // original image, instead of to the current screen orientation.
+ float[] surfacePolygon = rotate(convertRectToPoly(surfaceDimensions),
+ 2 * currentDisplayOrientation / 90);
+ float[] desiredPolygon = convertRectToPoly(desiredBounds);
+
+ Matrix transform = new Matrix();
+ // Use polygons instead of rectangles so that rotation will be
+ // calculated, since that is not done by the new camera API.
+ transform.setPolyToPoly(surfacePolygon, 0, desiredPolygon, 0, 4);
+ return transform;
+ }
+
+ @Override
public boolean canDisableShutterSound() {
// The new API doesn't support this operation, so don't encourage people to try it.
// TODO: What kind of assumptions have callers made about this result's meaning?
return false;
}
+
+ private static float[] convertRectToPoly(RectF rf) {
+ return new float[] {rf.left, rf.top, rf.right, rf.top,
+ rf.right, rf.bottom, rf.left, rf.bottom};
+ }
+
+ private static float[] rotate(float[] arr, int times) {
+ if (times < 0) {
+ times = times % arr.length + arr.length;
+ }
+
+ float[] res = new float[arr.length];
+ for (int offset = 0; offset < arr.length; ++offset) {
+ res[offset] = arr[(times + offset) % arr.length];
+ }
+ return res;
+ }
}
}
diff --git a/camera2/portability/src/com/android/ex/camera2/portability/CameraDeviceInfo.java b/camera2/portability/src/com/android/ex/camera2/portability/CameraDeviceInfo.java
index a657170..72a641e 100644
--- a/camera2/portability/src/com/android/ex/camera2/portability/CameraDeviceInfo.java
+++ b/camera2/portability/src/com/android/ex/camera2/portability/CameraDeviceInfo.java
@@ -16,7 +16,8 @@
package com.android.ex.camera2.portability;
-import android.hardware.Camera;
+import android.graphics.Matrix;
+import android.graphics.RectF;
import com.android.ex.camera2.portability.debug.Log;
@@ -67,17 +68,18 @@ public interface CameraDeviceInfo {
public abstract boolean isFacingFront();
/**
- * @return The camera image orientation, or the clockwise rotation angle
- * that must be applied to display it in its natural orientation
- * (in degrees, always a multiple of 90, and between [90,270]).
+ * @return The camera sensor orientation, or the counterclockwise angle
+ * from its natural position that the device must be held at
+ * for the sensor to be right side up (in degrees, always a
+ * multiple of 90, and between 0 and 270, inclusive).
*/
public abstract int getSensorOrientation();
/**
* @param currentDisplayOrientation
- * The current display orientation, as measured clockwise from
- * the device's natural orientation (in degrees, always a
- * multiple of 90, and between 0 and 270, inclusive).
+ * The current display orientation, measured counterclockwise
+ * from to the device's natural orientation (in degrees, always
+ * a multiple of 90, and between 0 and 270, inclusive).
* @return
* The relative preview image orientation, or the clockwise
* rotation angle that must be applied to display preview
@@ -92,9 +94,9 @@ public interface CameraDeviceInfo {
/**
* @param currentDisplayOrientation
- * The current display orientation, as measured clockwise from
- * the device's natural orientation (in degrees, always a
- * multiple of 90, and between 0 and 270, inclusive).
+ * The current display orientation, measured counterclockwise
+ * from to the device's natural orientation (in degrees, always
+ * a multiple of 90, and between 0 and 270, inclusive).
* @return
* The relative capture image orientation, or the clockwise
* rotation angle that must be applied to display these frames
@@ -120,11 +122,8 @@ public interface CameraDeviceInfo {
*/
protected int getRelativeImageOrientation(int currentDisplayOrientation,
boolean compensateForMirroring) {
- if (currentDisplayOrientation % 90 != 0) {
- Log.e(TAG, "Provided display orientation is not divisible by 90");
- }
- if (currentDisplayOrientation < 0 || currentDisplayOrientation > 270) {
- Log.e(TAG, "Provided display orientation is outside expected range");
+ if (!orientationIsValid(currentDisplayOrientation)) {
+ return 0;
}
int result = 0;
@@ -142,8 +141,70 @@ public interface CameraDeviceInfo {
}
/**
+ * @param currentDisplayOrientation
+ * The current display orientation, measured counterclockwise
+ * from to the device's natural orientation (in degrees, always
+ * a multiple of 90, and between 0 and 270, inclusive).
+ * @param surfaceDimensions
+ * The dimensions of the {@link android.view.Surface} on which
+ * the preview image is being rendered. It usually only makes
+ * sense for the upper-left corner to be at the origin.
+ * @return
+ * The transform matrix that should be applied to the
+ * {@link android.view.Surface} in order for the image to
+ * display properly in the device's current orientation.
+ */
+ public Matrix getPreviewTransform(int currentDisplayOrientation, RectF surfaceDimensions) {
+ return getPreviewTransform(currentDisplayOrientation, surfaceDimensions,
+ new RectF(surfaceDimensions));
+ }
+
+ /**
+ * @param currentDisplayOrientation
+ * The current display orientation, measured counterclockwise
+ * from to the device's natural orientation (in degrees, always
+ * a multiple of 90, and between 0 and 270, inclusive).
+ * @param surfaceDimensions
+ * The dimensions of the {@link android.view.Surface} on which
+ * the preview image is being rendered. It usually only makes
+ * sense for the upper-left corner to be at the origin.
+ * @param desiredBounds
+ * The boundaries within the {@link android.view.Surface} where
+ * the final image should appear. These can be used to
+ * translate and scale the output, but note that the image will
+ * be stretched to fit, possibly changing its aspect ratio.
+ * @return
+ * The transform matrix that should be applied to the
+ * {@link android.view.Surface} in order for the image to
+ * display properly in the device's current orientation.
+ */
+ public Matrix getPreviewTransform(int currentDisplayOrientation, RectF surfaceDimensions,
+ RectF desiredBounds) {
+ if (!orientationIsValid(currentDisplayOrientation) ||
+ surfaceDimensions.equals(desiredBounds)) {
+ return new Matrix();
+ }
+
+ Matrix transform = new Matrix();
+ transform.setRectToRect(surfaceDimensions, desiredBounds, Matrix.ScaleToFit.FILL);
+ return transform;
+ }
+
+ /**
* @return Whether the shutter sound can be disabled.
*/
public abstract boolean canDisableShutterSound();
+
+ protected static boolean orientationIsValid(int angle) {
+ if (angle % 90 != 0) {
+ Log.e(TAG, "Provided display orientation is not divisible by 90");
+ return false;
+ }
+ if (angle < 0 || angle > 270) {
+ Log.e(TAG, "Provided display orientation is outside expected range");
+ return false;
+ }
+ return true;
+ }
}
}