diff options
author | Ray Chen <raychen@google.com> | 2009-07-20 16:33:41 +0800 |
---|---|---|
committer | Ray Chen <raychen@google.com> | 2009-07-29 19:00:13 +0800 |
commit | 012d0f38e1fd547436675257c5cd5c62928e2ed5 (patch) | |
tree | 884ff5188b25ea36698ac458cdf4e356c91e656c /src/com/android | |
parent | b53862357d977643c760c4eaeb0b7dcc841727f6 (diff) | |
download | LegacyCamera-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.java | 2 | ||||
-rw-r--r-- | src/com/android/camera/ImageGetter.java | 19 | ||||
-rw-r--r-- | src/com/android/camera/ImageViewTouchBase.java | 98 | ||||
-rw-r--r-- | src/com/android/camera/ReviewImage.java | 16 | ||||
-rw-r--r-- | src/com/android/camera/RotateBitmap.java | 97 | ||||
-rw-r--r-- | src/com/android/camera/VideoCamera.java | 2 | ||||
-rw-r--r-- | src/com/android/camera/ViewImage.java | 16 | ||||
-rw-r--r-- | src/com/android/camera/gallery/BaseImage.java | 9 | ||||
-rw-r--r-- | src/com/android/camera/gallery/DrmImageList.java | 7 | ||||
-rw-r--r-- | src/com/android/camera/gallery/IImage.java | 8 | ||||
-rw-r--r-- | src/com/android/camera/gallery/Image.java | 9 | ||||
-rw-r--r-- | src/com/android/camera/gallery/UriImage.java | 17 | ||||
-rw-r--r-- | src/com/android/camera/gallery/VideoObject.java | 2 |
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); } |