summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei-Ta Chen <weita@google.com>2011-11-11 19:07:58 -0800
committerWei-Ta Chen <weita@google.com>2011-11-15 13:48:22 -0800
commite0bbb93f6a598206ecd6e09150d51eae64bd3507 (patch)
treedcd04dcce28bd93dc41c98b5659fc91babbffd19
parent34238165cfdf04584587360dfcf21109bf09e144 (diff)
downloadLegacyCamera-e0bbb93f6a598206ecd6e09150d51eae64bd3507.zip
LegacyCamera-e0bbb93f6a598206ecd6e09150d51eae64bd3507.tar.gz
LegacyCamera-e0bbb93f6a598206ecd6e09150d51eae64bd3507.tar.bz2
Set the orientation of a panorama image.
The panorama image returned from the panorama library is oriented based on the natural orientation of the camera. We set an orientation in its EXIF header, so that the image can be displayed correctly. The orientation is calculated by compensating the device orientation and the camera orientation respective to the natural orientation of the device. Bug: 5603313 Change-Id: Id6907cb08a7ff77e44736f3c3cd1503e7a68d783
-rw-r--r--src/com/android/camera/Storage.java6
-rw-r--r--src/com/android/camera/Util.java6
-rwxr-xr-xsrc/com/android/camera/panorama/PanoramaActivity.java49
3 files changed, 56 insertions, 5 deletions
diff --git a/src/com/android/camera/Storage.java b/src/com/android/camera/Storage.java
index 38a6d48..ea281a9 100644
--- a/src/com/android/camera/Storage.java
+++ b/src/com/android/camera/Storage.java
@@ -52,7 +52,7 @@ public class Storage {
public static Uri addImage(ContentResolver resolver, String title, long date,
Location location, int orientation, byte[] jpeg, int width, int height) {
// Save the image.
- String path = DIRECTORY + '/' + title + ".jpg";
+ String path = generateFilepath(title);
FileOutputStream out = null;
try {
out = new FileOutputStream(path);
@@ -98,6 +98,10 @@ public class Storage {
return uri;
}
+ public static String generateFilepath(String title) {
+ return DIRECTORY + '/' + title + ".jpg";
+ }
+
public static long getAvailableSpace() {
String state = Environment.getExternalStorageState();
Log.d(TAG, "External storage state=" + state);
diff --git a/src/com/android/camera/Util.java b/src/com/android/camera/Util.java
index ba8a4f7..d6ebb0a 100644
--- a/src/com/android/camera/Util.java
+++ b/src/com/android/camera/Util.java
@@ -350,6 +350,12 @@ public class Util {
return result;
}
+ public static int getCameraOrientation(int cameraId) {
+ Camera.CameraInfo info = new Camera.CameraInfo();
+ Camera.getCameraInfo(cameraId, info);
+ return info.orientation;
+ }
+
public static int roundOrientation(int orientation, int orientationHistory) {
boolean changeOrientation = false;
if (orientationHistory == OrientationEventListener.ORIENTATION_UNKNOWN) {
diff --git a/src/com/android/camera/panorama/PanoramaActivity.java b/src/com/android/camera/panorama/PanoramaActivity.java
index fe70827..331c849 100755
--- a/src/com/android/camera/panorama/PanoramaActivity.java
+++ b/src/com/android/camera/panorama/PanoramaActivity.java
@@ -52,6 +52,7 @@ import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.hardware.Sensor;
import android.hardware.SensorManager;
+import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -71,6 +72,7 @@ import android.widget.TextView;
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.IOException;
import java.util.List;
/**
@@ -177,6 +179,8 @@ public class PanoramaActivity extends ActivityBase implements
// The value could be 0, 90, 180, 270 for the 4 different orientations measured in clockwise
// respectively.
private int mDeviceOrientation;
+ private int mDeviceOrientationAtCapture;
+ private int mCameraOrientation;
private int mOrientationCompensation;
private RotateDialogController mRotateDialog;
@@ -343,7 +347,9 @@ public class PanoramaActivity extends ActivityBase implements
private void openCamera() {
try {
- mCameraDevice = Util.openCamera(this, CameraHolder.instance().getBackCameraId());
+ int backCameraId = CameraHolder.instance().getBackCameraId();
+ mCameraDevice = Util.openCamera(this, backCameraId);
+ mCameraOrientation = Util.getCameraOrientation(backCameraId);
} catch (CameraHardwareException e) {
Util.showErrorAndFinish(this, R.string.cannot_connect_camera);
return;
@@ -573,6 +579,7 @@ public class PanoramaActivity extends ActivityBase implements
mPanoProgressBar.setIndicatorWidth(20);
mPanoProgressBar.setMaxProgress(DEFAULT_SWEEP_ANGLE);
mPanoProgressBar.setVisibility(View.VISIBLE);
+ mDeviceOrientationAtCapture = mDeviceOrientation;
keepScreenOn();
}
@@ -804,7 +811,13 @@ public class PanoramaActivity extends ActivityBase implements
} else if (!jpeg.isValid) { // Error when generating mosaic.
mMainHandler.sendEmptyMessage(MSG_GENERATE_FINAL_MOSAIC_ERROR);
} else {
- int orientation = Exif.getOrientation(jpeg.data);
+ // The panorama image returned from the library is orientated based on the
+ // natural orientation of a camera. We need to set an orientation for the image
+ // in its EXIF header, so the image can be displayed correctly.
+ // The orientation is calculated from compensating the
+ // device orientation at capture and the camera orientation respective to
+ // the natural orientation of the device.
+ int orientation = (mDeviceOrientationAtCapture + mCameraOrientation) % 360;
Uri uri = savePanorama(jpeg.data, jpeg.width, jpeg.height, orientation);
if (uri != null) {
// Create a thumbnail whose width or height is equal or bigger
@@ -894,14 +907,42 @@ public class PanoramaActivity extends ActivityBase implements
private Uri savePanorama(byte[] jpegData, int width, int height, int orientation) {
if (jpegData != null) {
- String imagePath = PanoUtil.createName(
+ String filename = PanoUtil.createName(
getResources().getString(R.string.pano_file_name_format), mTimeTaken);
- return Storage.addImage(getContentResolver(), imagePath, mTimeTaken, null,
+ Uri uri = Storage.addImage(getContentResolver(), filename, mTimeTaken, null,
orientation, jpegData, width, height);
+ if (uri != null && orientation != 0) {
+ String filepath = Storage.generateFilepath(filename);
+ try {
+ // Save the orientation in EXIF.
+ ExifInterface exif = new ExifInterface(filepath);
+ exif.setAttribute(ExifInterface.TAG_ORIENTATION,
+ getExifOrientation(orientation));
+ exif.saveAttributes();
+ } catch (IOException e) {
+ Log.e(TAG, "cannot set exif data: " + filepath);
+ }
+ }
+ return uri;
}
return null;
}
+ private static String getExifOrientation(int orientation) {
+ switch (orientation) {
+ case 0:
+ return String.valueOf(ExifInterface.ORIENTATION_NORMAL);
+ case 90:
+ return String.valueOf(ExifInterface.ORIENTATION_ROTATE_90);
+ case 180:
+ return String.valueOf(ExifInterface.ORIENTATION_ROTATE_180);
+ case 270:
+ return String.valueOf(ExifInterface.ORIENTATION_ROTATE_270);
+ default:
+ throw new AssertionError("invalid: " + orientation);
+ }
+ }
+
private void clearMosaicFrameProcessorIfNeeded() {
if (!mPausing || mThreadRunning) return;
mMosaicFrameProcessor.clear();