diff options
-rw-r--r-- | src/com/android/camera/Storage.java | 6 | ||||
-rw-r--r-- | src/com/android/camera/Util.java | 6 | ||||
-rwxr-xr-x | src/com/android/camera/panorama/PanoramaActivity.java | 49 |
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(); |