summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoris Liu <tianliu@google.com>2013-09-16 13:38:24 -0700
committerDoris Liu <tianliu@google.com>2013-09-16 18:36:17 -0700
commit87fc5e1568f737e03327770cb3dee03c4b939c59 (patch)
tree3152897732163001feaa2afbe59a03fb3627b185
parentd688c0c31d4287c03b664f6fca5c6498a1e4bd7d (diff)
downloadandroid_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
-rw-r--r--src/com/android/camera/data/LocalMediaData.java6
-rw-r--r--src/com/android/camera/data/SimpleViewData.java5
-rw-r--r--src/com/android/camera/ui/FilmStripView.java18
-rw-r--r--src/com/android/camera/ui/ZoomView.java51
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();