summaryrefslogtreecommitdiffstats
path: root/src/com/android
diff options
context:
space:
mode:
authorRay Chen <raychen@google.com>2009-07-20 16:33:41 +0800
committerRay Chen <raychen@google.com>2009-07-29 19:00:13 +0800
commit012d0f38e1fd547436675257c5cd5c62928e2ed5 (patch)
tree884ff5188b25ea36698ac458cdf4e356c91e656c /src/com/android
parentb53862357d977643c760c4eaeb0b7dcc841727f6 (diff)
downloadLegacyCamera-012d0f38e1fd547436675257c5cd5c62928e2ed5.zip
LegacyCamera-012d0f38e1fd547436675257c5cd5c62928e2ed5.tar.gz
LegacyCamera-012d0f38e1fd547436675257c5cd5c62928e2ed5.tar.bz2
Defer bitmap rotation until it's drawn on ImageView.
Diffstat (limited to 'src/com/android')
-rw-r--r--src/com/android/camera/CropImage.java2
-rw-r--r--src/com/android/camera/ImageGetter.java19
-rw-r--r--src/com/android/camera/ImageViewTouchBase.java98
-rw-r--r--src/com/android/camera/ReviewImage.java16
-rw-r--r--src/com/android/camera/RotateBitmap.java97
-rw-r--r--src/com/android/camera/VideoCamera.java2
-rw-r--r--src/com/android/camera/ViewImage.java16
-rw-r--r--src/com/android/camera/gallery/BaseImage.java9
-rw-r--r--src/com/android/camera/gallery/DrmImageList.java7
-rw-r--r--src/com/android/camera/gallery/IImage.java8
-rw-r--r--src/com/android/camera/gallery/Image.java9
-rw-r--r--src/com/android/camera/gallery/UriImage.java17
-rw-r--r--src/com/android/camera/gallery/VideoObject.java2
13 files changed, 226 insertions, 76 deletions
diff --git a/src/com/android/camera/CropImage.java b/src/com/android/camera/CropImage.java
index 0612dc3..118adce 100644
--- a/src/com/android/camera/CropImage.java
+++ b/src/com/android/camera/CropImage.java
@@ -136,7 +136,7 @@ public class CropImage extends MonitoredActivity {
// instead.
// TODO when saving the resulting bitmap use the
// decode/crop/encode api so we don't lose any resolution.
- mBitmap = mImage.thumbBitmap();
+ mBitmap = mImage.thumbBitmap(IImage.ROTATE_AS_NEEDED);
}
}
diff --git a/src/com/android/camera/ImageGetter.java b/src/com/android/camera/ImageGetter.java
index b7d47e9..5b2afe4 100644
--- a/src/com/android/camera/ImageGetter.java
+++ b/src/com/android/camera/ImageGetter.java
@@ -47,7 +47,7 @@ import android.os.Message;
*/
interface ImageGetterCallback {
- public void imageLoaded(int pos, int offset, Bitmap bitmap,
+ public void imageLoaded(int pos, int offset, RotateBitmap bitmap,
boolean isThumb);
public boolean wantsThumbnail(int pos, int offset);
public boolean wantsFullImage(int pos, int offset);
@@ -95,7 +95,8 @@ class ImageGetter {
private class ImageGetterRunnable implements Runnable {
private Runnable callback(final int position, final int offset,
- final boolean isThumb, final Bitmap bitmap,
+ final boolean isThumb,
+ final RotateBitmap bitmap,
final int requestSerial) {
return new Runnable() {
public void run() {
@@ -160,7 +161,7 @@ class ImageGetter {
if (image == null) continue;
if (mCancel) return;
- Bitmap b = image.thumbBitmap();
+ Bitmap b = image.thumbBitmap(IImage.NO_ROTATE);
if (b == null) continue;
if (mCancel) {
b.recycle();
@@ -168,7 +169,9 @@ class ImageGetter {
}
Runnable cb = callback(mCurrentPosition, offset,
- true, b, mCurrentSerial);
+ true,
+ new RotateBitmap(b, image.getDegreesRotated()),
+ mCurrentSerial);
mHandler.postGetterCallback(cb);
}
}
@@ -190,15 +193,19 @@ class ImageGetter {
int sizeToUse = mCB.fullImageSizeToUse(
mCurrentPosition, offset);
Bitmap b = image.fullSizeBitmap(sizeToUse, 3 * 1024 * 1024,
- IImage.ROTATE_AS_NEEDED, IImage.USE_NATIVE);
+ IImage.NO_ROTATE, IImage.USE_NATIVE);
+
if (b == null) continue;
if (mCancel) {
b.recycle();
return;
}
+ RotateBitmap rb = new RotateBitmap(b,
+ image.getDegreesRotated());
+
Runnable cb = callback(mCurrentPosition, offset,
- false, b, mCurrentSerial);
+ false, rb, mCurrentSerial);
mHandler.postGetterCallback(cb);
}
}
diff --git a/src/com/android/camera/ImageViewTouchBase.java b/src/com/android/camera/ImageViewTouchBase.java
index bc33827..1812466 100644
--- a/src/com/android/camera/ImageViewTouchBase.java
+++ b/src/com/android/camera/ImageViewTouchBase.java
@@ -19,9 +19,11 @@ package com.android.camera;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
+import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.KeyEvent;
import android.widget.ImageView;
@@ -54,7 +56,7 @@ abstract class ImageViewTouchBase extends ImageView {
private final float[] mMatrixValues = new float[9];
// The current bitmap being displayed.
- protected Bitmap mBitmapDisplayed;
+ final protected RotateBitmap mBitmapDisplayed = new RotateBitmap(null);
int mThisWidth = -1, mThisHeight = -1;
@@ -83,7 +85,7 @@ abstract class ImageViewTouchBase extends ImageView {
mOnLayoutRunnable = null;
r.run();
}
- if (mBitmapDisplayed != null) {
+ if (mBitmapDisplayed.getBitmap() != null) {
getProperBaseMatrix(mBitmapDisplayed, mBaseMatrix);
setImageMatrix(getImageViewMatrix());
}
@@ -107,14 +109,20 @@ abstract class ImageViewTouchBase extends ImageView {
@Override
public void setImageBitmap(Bitmap bitmap) {
+ setImageBitmap(bitmap, 0);
+ }
+
+ private void setImageBitmap(Bitmap bitmap, int rotation) {
super.setImageBitmap(bitmap);
Drawable d = getDrawable();
if (d != null) {
d.setDither(true);
}
- Bitmap old = mBitmapDisplayed;
- mBitmapDisplayed = bitmap;
+ Bitmap old = mBitmapDisplayed.getBitmap();
+ mBitmapDisplayed.setBitmap(bitmap);
+ mBitmapDisplayed.setRotation(rotation);
+
if (old != null && old != bitmap && mRecycler != null) {
mRecycler.recycle(old);
}
@@ -130,20 +138,25 @@ abstract class ImageViewTouchBase extends ImageView {
// of the bitmap, and optionally reset the supplementary matrix.
public void setImageBitmapResetBase(final Bitmap bitmap,
final boolean resetSupp) {
+ setImageRotateBitmapResetBase(new RotateBitmap(bitmap), resetSupp);
+ }
+
+ public void setImageRotateBitmapResetBase(final RotateBitmap bitmap,
+ final boolean resetSupp) {
final int viewWidth = getWidth();
if (viewWidth <= 0) {
mOnLayoutRunnable = new Runnable() {
public void run() {
- setImageBitmapResetBase(bitmap, resetSupp);
+ setImageRotateBitmapResetBase(bitmap, resetSupp);
}
};
return;
}
- if (bitmap != null) {
+ if (bitmap.getBitmap() != null) {
getProperBaseMatrix(bitmap, mBaseMatrix);
- setImageBitmap(bitmap);
+ setImageBitmap(bitmap.getBitmap(), bitmap.getRotation());
} else {
mBaseMatrix.reset();
setImageBitmap(null);
@@ -162,43 +175,42 @@ abstract class ImageViewTouchBase extends ImageView {
// is scaled larger than the view and is translated out of view
// then translate it back into view (i.e. eliminate black bars).
protected void center(boolean horizontal, boolean vertical) {
- if (mBitmapDisplayed == null) {
+ if (mBitmapDisplayed.getBitmap() == null) {
return;
}
Matrix m = getImageViewMatrix();
- float [] topLeft = new float[] { 0, 0 };
- float [] botRight = new float[] { mBitmapDisplayed.getWidth(),
- mBitmapDisplayed.getHeight() };
+ RectF rect = new RectF(0, 0,
+ mBitmapDisplayed.getBitmap().getWidth(),
+ mBitmapDisplayed.getBitmap().getHeight());
- m.mapPoints(topLeft);
- m.mapPoints(botRight);
+ m.mapRect(rect);
- float height = botRight[1] - topLeft[1];
- float width = botRight[0] - topLeft[0];
+ float height = rect.height();
+ float width = rect.width();
float deltaX = 0, deltaY = 0;
if (vertical) {
int viewHeight = getHeight();
if (height < viewHeight) {
- deltaY = (viewHeight - height) / 2 - topLeft[1];
- } else if (topLeft[1] > 0) {
- deltaY = -topLeft[1];
- } else if (botRight[1] < viewHeight) {
- deltaY = getHeight() - botRight[1];
+ deltaY = (viewHeight - height) / 2 - rect.top;
+ } else if (rect.top > 0) {
+ deltaY = -rect.top;
+ } else if (rect.bottom < viewHeight) {
+ deltaY = getHeight() - rect.bottom;
}
}
if (horizontal) {
int viewWidth = getWidth();
if (width < viewWidth) {
- deltaX = (viewWidth - width) / 2 - topLeft[0];
- } else if (topLeft[0] > 0) {
- deltaX = -topLeft[0];
- } else if (botRight[0] < viewWidth) {
- deltaX = viewWidth - botRight[0];
+ deltaX = (viewWidth - width) / 2 - rect.left;
+ } else if (rect.left > 0) {
+ deltaX = -rect.left;
+ } else if (rect.right < viewWidth) {
+ deltaX = viewWidth - rect.right;
}
}
@@ -235,25 +247,27 @@ abstract class ImageViewTouchBase extends ImageView {
}
// Setup the base matrix so that the image is centered and scaled properly.
- private void getProperBaseMatrix(Bitmap bitmap, Matrix matrix) {
+ private void getProperBaseMatrix(RotateBitmap bitmap, Matrix matrix) {
float viewWidth = getWidth();
float viewHeight = getHeight();
+ float w = bitmap.getWidth();
+ float h = bitmap.getHeight();
+ int rotation = bitmap.getRotation();
matrix.reset();
- float widthScale = Math.min(viewWidth / bitmap.getWidth(),
- 1.0f);
- float heightScale = Math.min(viewHeight / bitmap.getHeight(),
- 1.0f);
- float scale;
- if (widthScale > heightScale) {
- scale = heightScale;
- } else {
- scale = widthScale;
- }
- matrix.setScale(scale, scale);
+
+ // Up-scaling is not allowed because the result may look bad if it's
+ // a thumbnail icon.
+ float widthScale = Math.min(viewWidth / w, 1.0f);
+ float heightScale = Math.min(viewHeight / h, 1.0f);
+ float scale = Math.min(widthScale, heightScale);
+
+ matrix.postConcat(bitmap.getRotateMatrix());
+ matrix.postScale(scale, scale);
+
matrix.postTranslate(
- (viewWidth - (bitmap.getWidth() * scale)) / 2F,
- (viewHeight - (bitmap.getHeight() * scale)) / 2F);
+ (viewWidth - w * scale) / 2F,
+ (viewHeight - h * scale) / 2F);
}
// Combine the base matrix and the supp matrix to make the final matrix.
@@ -272,7 +286,7 @@ abstract class ImageViewTouchBase extends ImageView {
// image orientation. If in the future we decode the full 3 megapixel image,
// rather than the current 1024x768, this should be changed down to 200%.
protected float maxZoom() {
- if (mBitmapDisplayed == null) {
+ if (mBitmapDisplayed.getBitmap() == null) {
return 1F;
}
@@ -334,7 +348,7 @@ abstract class ImageViewTouchBase extends ImageView {
if (getScale() >= mMaxZoom) {
return; // Don't let the user zoom into the molecular level.
}
- if (mBitmapDisplayed == null) {
+ if (mBitmapDisplayed.getBitmap() == null) {
return;
}
@@ -346,7 +360,7 @@ abstract class ImageViewTouchBase extends ImageView {
}
protected void zoomOut(float rate) {
- if (mBitmapDisplayed == null) {
+ if (mBitmapDisplayed.getBitmap() == null) {
return;
}
diff --git a/src/com/android/camera/ReviewImage.java b/src/com/android/camera/ReviewImage.java
index f92b249..6ed87fe 100644
--- a/src/com/android/camera/ReviewImage.java
+++ b/src/com/android/camera/ReviewImage.java
@@ -425,7 +425,9 @@ public class ReviewImage extends Activity implements View.OnClickListener {
Bitmap b = mCache.getBitmap(pos);
if (b != null) {
- mImageView.setImageBitmapResetBase(b, true);
+ IImage image = mAllImages.getImageAt(pos);
+ mImageView.setImageRotateBitmapResetBase(
+ new RotateBitmap(b, image.getDegreesRotated()), true);
updateZoomButtonsEnabled();
}
@@ -458,7 +460,7 @@ public class ReviewImage extends Activity implements View.OnClickListener {
return sOrderAdjacents;
}
- public void imageLoaded(int pos, int offset, Bitmap bitmap,
+ public void imageLoaded(int pos, int offset, RotateBitmap bitmap,
boolean isThumb) {
// shouldn't get here after onPause()
@@ -469,13 +471,13 @@ public class ReviewImage extends Activity implements View.OnClickListener {
}
if (isThumb) {
- mCache.put(pos + offset, bitmap);
+ mCache.put(pos + offset, bitmap.getBitmap());
}
if (offset == 0) {
// isThumb: We always load thumb bitmap first, so we will
// reset the supp matrix for then thumb bitmap, and keep
// the supp matrix when the full bitmap is loaded.
- mImageView.setImageBitmapResetBase(bitmap, isThumb);
+ mImageView.setImageRotateBitmapResetBase(bitmap, isThumb);
updateZoomButtonsEnabled();
}
}
@@ -736,7 +738,7 @@ public class ReviewImage extends Activity implements View.OnClickListener {
}
public void imageLoaded(final int pos, final int offset,
- final Bitmap bitmap, final boolean isThumb) {
+ final RotateBitmap bitmap, final boolean isThumb) {
long timeRemaining = Math.max(0,
targetDisplayTime - System.currentTimeMillis());
mHandler.postDelayedGetterCallback(new Runnable() {
@@ -756,7 +758,7 @@ public class ReviewImage extends Activity implements View.OnClickListener {
ImageViewTouchBase newView =
mSlideShowImageViews[mSlideShowImageCurrent];
newView.setVisibility(View.VISIBLE);
- newView.setImageBitmapResetBase(bitmap, true);
+ newView.setImageRotateBitmapResetBase(bitmap, true);
newView.bringToFront();
int animation = 0;
@@ -1101,7 +1103,7 @@ class ImageViewTouch2 extends ImageViewTouchBase {
protected boolean isShiftedToNextImage(boolean left, int maxOffset) {
boolean retval;
- Bitmap bitmap = mBitmapDisplayed;
+ RotateBitmap bitmap = mBitmapDisplayed;
Matrix m = getImageViewMatrix();
if (left) {
float [] t1 = new float[] { 0, 0 };
diff --git a/src/com/android/camera/RotateBitmap.java b/src/com/android/camera/RotateBitmap.java
new file mode 100644
index 0000000..1f72b17
--- /dev/null
+++ b/src/com/android/camera/RotateBitmap.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.camera;
+
+import android.graphics.Bitmap;
+import android.graphics.Matrix;
+import android.util.Log;
+
+public class RotateBitmap {
+ public static final String TAG = "RotateBitmap";
+ private Bitmap mBitmap;
+ private int mRotation;
+
+ public RotateBitmap(Bitmap bitmap) {
+ mBitmap = bitmap;
+ mRotation = 0;
+ }
+
+ public RotateBitmap(Bitmap bitmap, int rotation) {
+ mBitmap = bitmap;
+ mRotation = rotation % 360;
+ }
+
+ public void setRotation(int rotation) {
+ mRotation = rotation;
+ }
+
+ public int getRotation() {
+ return mRotation;
+ }
+
+ public Bitmap getBitmap() {
+ return mBitmap;
+ }
+
+ public void setBitmap(Bitmap bitmap) {
+ mBitmap = bitmap;
+ }
+
+ public Matrix getRotateMatrix() {
+ // By default this is an identity matrix.
+ Matrix matrix = new Matrix();
+ if (mRotation != 0) {
+ // We want to do the rotation at origin, but since the bounding
+ // rectangle will be changed after rotation, so the delta values
+ // are based on old & new width/height respectively.
+ int cx = mBitmap.getWidth() / 2;
+ int cy = mBitmap.getHeight() / 2;
+ matrix.preTranslate(-cx, -cy);
+ matrix.postRotate(mRotation);
+ matrix.postTranslate(getWidth() / 2, getHeight() / 2);
+ }
+ return matrix;
+ }
+
+ public boolean isOrientationChanged() {
+ return (mRotation / 90) % 2 != 0;
+ }
+
+ public int getHeight() {
+ if (isOrientationChanged()) {
+ return mBitmap.getWidth();
+ } else {
+ return mBitmap.getHeight();
+ }
+ }
+
+ public int getWidth() {
+ if (isOrientationChanged()) {
+ return mBitmap.getHeight();
+ } else {
+ return mBitmap.getWidth();
+ }
+ }
+
+ public void recycle() {
+ if (mBitmap != null) {
+ mBitmap.recycle();
+ mBitmap = null;
+ }
+ }
+}
+
diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java
index f404145..a60ed5c 100644
--- a/src/com/android/camera/VideoCamera.java
+++ b/src/com/android/camera/VideoCamera.java
@@ -1269,7 +1269,7 @@ public class VideoCamera extends Activity implements View.OnClickListener,
// Starting a minute before reaching the max duration
// limit, we'll countdown the remaining time instead.
- boolean countdownRemainingTime = (mMaxVideoDurationInMs != 0
+ boolean countdownRemainingTime = (mMaxVideoDurationInMs != 0
&& delta >= mMaxVideoDurationInMs - 60000);
if (countdownRemainingTime) {
diff --git a/src/com/android/camera/ViewImage.java b/src/com/android/camera/ViewImage.java
index 02ef981..6486d2d 100644
--- a/src/com/android/camera/ViewImage.java
+++ b/src/com/android/camera/ViewImage.java
@@ -462,7 +462,9 @@ public class ViewImage extends Activity implements View.OnClickListener {
Bitmap b = mCache.getBitmap(pos);
if (b != null) {
- mImageView.setImageBitmapResetBase(b, true);
+ IImage image = mAllImages.getImageAt(pos);
+ mImageView.setImageRotateBitmapResetBase(
+ new RotateBitmap(b, image.getDegreesRotated()), true);
updateZoomButtonsEnabled();
}
@@ -497,7 +499,7 @@ public class ViewImage extends Activity implements View.OnClickListener {
return sOrderAdjacents;
}
- public void imageLoaded(int pos, int offset, Bitmap bitmap,
+ public void imageLoaded(int pos, int offset, RotateBitmap bitmap,
boolean isThumb) {
// shouldn't get here after onPause()
@@ -508,13 +510,13 @@ public class ViewImage extends Activity implements View.OnClickListener {
}
if (isThumb) {
- mCache.put(pos + offset, bitmap);
+ mCache.put(pos + offset, bitmap.getBitmap());
}
if (offset == 0) {
// isThumb: We always load thumb bitmap first, so we will
// reset the supp matrix for then thumb bitmap, and keep
// the supp matrix when the full bitmap is loaded.
- mImageView.setImageBitmapResetBase(bitmap, isThumb);
+ mImageView.setImageRotateBitmapResetBase(bitmap, isThumb);
updateZoomButtonsEnabled();
}
}
@@ -794,7 +796,7 @@ public class ViewImage extends Activity implements View.OnClickListener {
}
public void imageLoaded(final int pos, final int offset,
- final Bitmap bitmap, final boolean isThumb) {
+ final RotateBitmap bitmap, final boolean isThumb) {
long timeRemaining = Math.max(0,
targetDisplayTime - System.currentTimeMillis());
mHandler.postDelayedGetterCallback(new Runnable() {
@@ -814,7 +816,7 @@ public class ViewImage extends Activity implements View.OnClickListener {
ImageViewTouchBase newView =
mSlideShowImageViews[mSlideShowImageCurrent];
newView.setVisibility(View.VISIBLE);
- newView.setImageBitmapResetBase(bitmap, true);
+ newView.setImageRotateBitmapResetBase(bitmap, true);
newView.bringToFront();
int animation = 0;
@@ -1169,7 +1171,7 @@ class ImageViewTouch extends ImageViewTouchBase {
protected boolean isShiftedToNextImage(boolean left, int maxOffset) {
boolean retval;
- Bitmap bitmap = mBitmapDisplayed;
+ RotateBitmap bitmap = mBitmapDisplayed;
Matrix m = getImageViewMatrix();
if (left) {
float [] t1 = new float[] { 0, 0 };
diff --git a/src/com/android/camera/gallery/BaseImage.java b/src/com/android/camera/gallery/BaseImage.java
index 4ff963c..8f0525a 100644
--- a/src/com/android/camera/gallery/BaseImage.java
+++ b/src/com/android/camera/gallery/BaseImage.java
@@ -164,6 +164,12 @@ public abstract class BaseImage implements IImage {
}
public Bitmap fullSizeBitmap(int minSideLength, int maxNumberOfPixels,
+ boolean rotateAsNeeded) {
+ return fullSizeBitmap(minSideLength, maxNumberOfPixels,
+ rotateAsNeeded, IImage.NO_NATIVE);
+ }
+
+ public Bitmap fullSizeBitmap(int minSideLength, int maxNumberOfPixels,
boolean rotateAsNeeded, boolean useNative) {
Uri url = mContainer.contentUri(mId);
if (url == null) return null;
@@ -174,6 +180,7 @@ public abstract class BaseImage implements IImage {
if (b != null && rotateAsNeeded) {
b = Util.rotate(b, getDegreesRotated());
}
+
return b;
}
@@ -202,7 +209,7 @@ public abstract class BaseImage implements IImage {
return mDateTaken;
}
- protected int getDegreesRotated() {
+ public int getDegreesRotated() {
return 0;
}
diff --git a/src/com/android/camera/gallery/DrmImageList.java b/src/com/android/camera/gallery/DrmImageList.java
index 4791c8d..445d867 100644
--- a/src/com/android/camera/gallery/DrmImageList.java
+++ b/src/com/android/camera/gallery/DrmImageList.java
@@ -82,6 +82,11 @@ public class DrmImageList extends ImageList implements IImageList {
}
@Override
+ public int getDegreesRotated() {
+ return 0;
+ }
+
+ @Override
public boolean isDrm() {
return true;
}
@@ -98,7 +103,7 @@ public class DrmImageList extends ImageList implements IImageList {
}
@Override
- public Bitmap thumbBitmap() {
+ public Bitmap thumbBitmap(boolean rotateAsNeeded) {
return fullSizeBitmap(IImage.THUMBNAIL_TARGET_SIZE,
IImage.UNCONSTRAINED);
}
diff --git a/src/com/android/camera/gallery/IImage.java b/src/com/android/camera/gallery/IImage.java
index 8c9a6dd..50a3aba 100644
--- a/src/com/android/camera/gallery/IImage.java
+++ b/src/com/android/camera/gallery/IImage.java
@@ -34,9 +34,13 @@ public interface IImage {
public abstract IImageList getContainer();
/** Get the bitmap for the full size image. */
- public abstract Bitmap fullSizeBitmap(int minSideLength, int maxNumberOfPixels);
+ public abstract Bitmap fullSizeBitmap(int minSideLength,
+ int maxNumberOfPixels);
+ public abstract Bitmap fullSizeBitmap(int minSideLength,
+ int maxNumberOfPixels, boolean rotateAsNeeded);
public abstract Bitmap fullSizeBitmap(int minSideLength,
int maxNumberOfPixels, boolean rotateAsNeeded, boolean useNative);
+ public abstract int getDegreesRotated();
public static final boolean ROTATE_AS_NEEDED = true;
public static final boolean NO_ROTATE = false;
public static final boolean USE_NATIVE = true;
@@ -70,7 +74,7 @@ public interface IImage {
public abstract boolean isDrm();
// Get the bitmap/uri of the medium thumbnail
- public abstract Bitmap thumbBitmap();
+ public abstract Bitmap thumbBitmap(boolean rotateAsNeeded);
public abstract Uri thumbUri();
// Get the bitmap of the mini thumbnail.
diff --git a/src/com/android/camera/gallery/Image.java b/src/com/android/camera/gallery/Image.java
index 33fa46b..437c741 100644
--- a/src/com/android/camera/gallery/Image.java
+++ b/src/com/android/camera/gallery/Image.java
@@ -58,7 +58,7 @@ public class Image extends BaseImage implements IImage {
}
@Override
- protected int getDegreesRotated() {
+ public int getDegreesRotated() {
return mRotation;
}
@@ -199,6 +199,7 @@ public class Image extends BaseImage implements IImage {
private void setExifRotation(int degrees) {
try {
+ degrees %= 360;
if (degrees < 0) degrees += 360;
int orientation = ExifInterface.ORIENTATION_NORMAL;
@@ -233,7 +234,7 @@ public class Image extends BaseImage implements IImage {
* @param degrees
*/
public boolean rotateImageBy(int degrees) {
- int newDegrees = getDegreesRotated() + degrees;
+ int newDegrees = (getDegreesRotated() + degrees) % 360;
setExifRotation(newDegrees);
setDegreesRotated(newDegrees);
@@ -252,7 +253,7 @@ public class Image extends BaseImage implements IImage {
BaseColumns._ID,
};
- public Bitmap thumbBitmap() {
+ public Bitmap thumbBitmap(boolean rotateAsNeeded) {
Bitmap bitmap = null;
if (mContainer.mThumbUri != null) {
Cursor c = mContentResolver.query(
@@ -279,7 +280,7 @@ public class Image extends BaseImage implements IImage {
bitmap = mContainer.storeThumbnail(bitmap, mId);
}
- if (bitmap != null) {
+ if (bitmap != null && rotateAsNeeded) {
bitmap = Util.rotate(bitmap, getDegreesRotated());
}
diff --git a/src/com/android/camera/gallery/UriImage.java b/src/com/android/camera/gallery/UriImage.java
index e8f0363..2f5e42b 100644
--- a/src/com/android/camera/gallery/UriImage.java
+++ b/src/com/android/camera/gallery/UriImage.java
@@ -42,6 +42,10 @@ class UriImage implements IImage {
mUri = uri;
}
+ public int getDegreesRotated() {
+ return 0;
+ }
+
public String getDataPath() {
return mUri.getPath();
}
@@ -79,6 +83,12 @@ class UriImage implements IImage {
}
public Bitmap fullSizeBitmap(int minSideLength, int maxNumberOfPixels,
+ boolean rotateAsNeeded) {
+ return fullSizeBitmap(minSideLength, maxNumberOfPixels,
+ rotateAsNeeded, IImage.NO_NATIVE);
+ }
+
+ public Bitmap fullSizeBitmap(int minSideLength, int maxNumberOfPixels,
boolean rotateAsNeeded, boolean useNative) {
try {
ParcelFileDescriptor pfdInput = getPFD();
@@ -100,7 +110,7 @@ class UriImage implements IImage {
}
public Bitmap miniThumbBitmap() {
- return thumbBitmap();
+ return thumbBitmap(IImage.ROTATE_AS_NEEDED);
}
public String getTitle() {
@@ -111,8 +121,9 @@ class UriImage implements IImage {
return getTitle();
}
- public Bitmap thumbBitmap() {
- return fullSizeBitmap(THUMBNAIL_TARGET_SIZE, IImage.UNCONSTRAINED);
+ public Bitmap thumbBitmap(boolean rotateAsNeeded) {
+ return fullSizeBitmap(THUMBNAIL_TARGET_SIZE, IImage.UNCONSTRAINED,
+ rotateAsNeeded);
}
private BitmapFactory.Options snifBitmapOptions() {
diff --git a/src/com/android/camera/gallery/VideoObject.java b/src/com/android/camera/gallery/VideoObject.java
index cfde199..bb499f9 100644
--- a/src/com/android/camera/gallery/VideoObject.java
+++ b/src/com/android/camera/gallery/VideoObject.java
@@ -107,7 +107,7 @@ public class VideoObject extends BaseImage implements IImage {
return false;
}
- public Bitmap thumbBitmap() {
+ public Bitmap thumbBitmap(boolean rotateAsNeeded) {
return fullSizeBitmap(THUMBNAIL_TARGET_SIZE, UNCONSTRAINED);
}