diff options
author | Doris Liu <tianliu@google.com> | 2013-09-16 13:38:24 -0700 |
---|---|---|
committer | Doris Liu <tianliu@google.com> | 2013-09-16 18:36:17 -0700 |
commit | 87fc5e1568f737e03327770cb3dee03c4b939c59 (patch) | |
tree | 3152897732163001feaa2afbe59a03fb3627b185 /src | |
parent | d688c0c31d4287c03b664f6fca5c6498a1e4bd7d (diff) | |
download | android_packages_apps_Snap-87fc5e1568f737e03327770cb3dee03c4b939c59.tar.gz android_packages_apps_Snap-87fc5e1568f737e03327770cb3dee03c4b939c59.tar.bz2 android_packages_apps_Snap-87fc5e1568f737e03327770cb3dee03c4b939c59.zip |
Fix zoom for images with orientation tag
Bug: 10780042
Change-Id: I518bf8a6e2b53647398180e60b55533960ebe318
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/camera/data/LocalMediaData.java | 6 | ||||
-rw-r--r-- | src/com/android/camera/data/SimpleViewData.java | 5 | ||||
-rw-r--r-- | src/com/android/camera/ui/FilmStripView.java | 18 | ||||
-rw-r--r-- | src/com/android/camera/ui/ZoomView.java | 51 |
4 files changed, 66 insertions, 14 deletions
diff --git a/src/com/android/camera/data/LocalMediaData.java b/src/com/android/camera/data/LocalMediaData.java index 3679b08e4..573da45db 100644 --- a/src/com/android/camera/data/LocalMediaData.java +++ b/src/com/android/camera/data/LocalMediaData.java @@ -127,6 +127,11 @@ public abstract class LocalMediaData implements LocalData { } @Override + public int getOrientation() { + return 0; + } + + @Override public String getPath() { return mPath; } @@ -383,6 +388,7 @@ public abstract class LocalMediaData implements LocalData { return result; } + @Override public int getOrientation() { return mOrientation; } diff --git a/src/com/android/camera/data/SimpleViewData.java b/src/com/android/camera/data/SimpleViewData.java index 3ff17226a..a73a52ece 100644 --- a/src/com/android/camera/data/SimpleViewData.java +++ b/src/com/android/camera/data/SimpleViewData.java @@ -75,6 +75,11 @@ public class SimpleViewData implements LocalData { } @Override + public int getOrientation() { + return 0; + } + + @Override public int getViewType() { return FilmStripView.ImageData.TYPE_REMOVABLE_VIEW; } diff --git a/src/com/android/camera/ui/FilmStripView.java b/src/com/android/camera/ui/FilmStripView.java index abb2a84e5..b42aaffd0 100644 --- a/src/com/android/camera/ui/FilmStripView.java +++ b/src/com/android/camera/ui/FilmStripView.java @@ -159,6 +159,11 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { */ public int getHeight(); + /** + * Returns the orientation of the image. + */ + public int getOrientation(); + /** Returns the image data type */ public int getViewType(); @@ -2109,8 +2114,11 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { return; } ViewItem curr = mViewItem[mCurrentItem]; - if(curr == null || !mDataAdapter.getImageData(curr.getId()) - .isUIActionSupported(ImageData.ACTION_ZOOM)) { + if (curr == null) { + return; + } + ImageData imageData = mDataAdapter.getImageData(curr.getId()); + if(!imageData.isUIActionSupported(ImageData.ACTION_ZOOM)) { return; } Uri uri = getCurrentContentUri(); @@ -2118,7 +2126,8 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { if (uri == null || uri == Uri.EMPTY) { return; } - mZoomView.loadBitmap(uri, viewRect); + int orientation = imageData.getOrientation(); + mZoomView.loadBitmap(uri, orientation, viewRect); } private void cancelLoadingZoomedImage() { @@ -2435,6 +2444,9 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { ViewItem curr = mViewItem[mCurrentItem]; // Make sure the image is not overly scaled newScale = Math.min(newScale, mMaxScale); + if (newScale == mScale) { + return true; + } float postScale = newScale / mScale; curr.postScale(focusX, focusY, postScale, mDrawArea.width(), mDrawArea.height()); mScale = newScale; diff --git a/src/com/android/camera/ui/ZoomView.java b/src/com/android/camera/ui/ZoomView.java index c4a49042c..65c4f2e4a 100644 --- a/src/com/android/camera/ui/ZoomView.java +++ b/src/com/android/camera/ui/ZoomView.java @@ -47,35 +47,58 @@ public class ZoomView extends ImageView { private DecodePartialBitmap mPartialDecodingTask; private Uri mUri; + private int mOrientation; private class DecodePartialBitmap extends AsyncTask<RectF, Void, Bitmap> { @Override protected Bitmap doInBackground(RectF... params) { RectF endRect = params[0]; + + // Calculate the rotation matrix to apply orientation on the original image + // rect. + RectF fullResRect = new RectF(0, 0, mFullResImageWidth - 1, mFullResImageHeight - 1); + Matrix rotationMatrix = new Matrix(); + rotationMatrix.setRotate(mOrientation, 0, 0); + rotationMatrix.mapRect(fullResRect); + // Set the translation of the matrix so that after rotation, the top left + // of the image rect is at (0, 0) + rotationMatrix.postTranslate(-fullResRect.left, -fullResRect.top); + rotationMatrix.mapRect(fullResRect, new RectF(0, 0, mFullResImageWidth - 1, + mFullResImageHeight - 1)); + // Find intersection with the screen RectF visibleRect = new RectF(endRect); visibleRect.intersect(0, 0, mViewportWidth - 1, mViewportHeight - 1); + // Calculate the mapping (i.e. transform) between current low res rect + // and full res image rect, and apply the mapping on current visible rect + // to find out the partial region in the full res image that we need + // to decode. + Matrix mapping = new Matrix(); + mapping.setRectToRect(endRect, fullResRect, Matrix.ScaleToFit.CENTER); + RectF visibleAfterRotation = new RectF(); + mapping.mapRect(visibleAfterRotation, visibleRect); - Matrix m2 = new Matrix(); - m2.setRectToRect(endRect, new RectF(0, 0, mFullResImageWidth - 1, - mFullResImageHeight - 1), Matrix.ScaleToFit.CENTER); + // Now the visible region we have is rotated, we need to reverse the + // rotation to find out the region in the original image RectF visibleInImage = new RectF(); - m2.mapRect(visibleInImage, visibleRect); + Matrix invertRotation = new Matrix(); + rotationMatrix.invert(invertRotation); + invertRotation.mapRect(visibleInImage, visibleAfterRotation); // Decode region - Rect v = new Rect(); - visibleInImage.round(v); + Rect region = new Rect(); + visibleInImage.round(region); // Make sure region to decode is inside the image. - v.intersect(0, 0, mFullResImageWidth - 1, mFullResImageHeight - 1); + region.intersect(0, 0, mFullResImageWidth - 1, mFullResImageHeight - 1); if (isCancelled()) { return null; } BitmapFactory.Options options = new BitmapFactory.Options(); - options.inSampleSize = getSampleFactor(v.width(), v.height()); + options.inSampleSize = getSampleFactor(region.width(), region.height()); if (mRegionDecoder == null) { InputStream is = getInputStream(); try { @@ -88,8 +111,13 @@ public class ZoomView extends ImageView { if (mRegionDecoder == null) { return null; } - Bitmap b = mRegionDecoder.decodeRegion(v, options); - return b; + Bitmap b = mRegionDecoder.decodeRegion(region, options); + if (isCancelled()) { + return null; + } + Matrix rotation = new Matrix(); + rotation.setRotate(mOrientation); + return Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), rotation, false); } @Override @@ -120,9 +148,10 @@ public class ZoomView extends ImageView { }); } - public void loadBitmap(Uri uri, RectF imageRect) { + public void loadBitmap(Uri uri, int orientation, RectF imageRect) { if (!uri.equals(mUri)) { mUri = uri; + mOrientation = orientation; mFullResImageHeight = 0; mFullResImageWidth = 0; decodeImageSize(); |