From 180282b9c90e2b387e6c65f1b35bb637c170aacf Mon Sep 17 00:00:00 2001 From: nicolasroard Date: Thu, 25 Oct 2012 20:14:02 -0700 Subject: Fix zooming position bug:7386221 Change-Id: I70215d3c3e12d08eee40a3cc848e3fc50f7dda75 --- .../gallery3d/filtershow/FilterShowActivity.java | 1 + .../gallery3d/filtershow/cache/ImageLoader.java | 22 +++-- .../filtershow/imageshow/GeometryMetadata.java | 98 +++++++++++++++++++++- .../gallery3d/filtershow/imageshow/ImageZoom.java | 90 +++++++++++++++----- 4 files changed, 180 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/com/android/gallery3d/filtershow/FilterShowActivity.java b/src/com/android/gallery3d/filtershow/FilterShowActivity.java index 1ed45eda2..ef0415f94 100644 --- a/src/com/android/gallery3d/filtershow/FilterShowActivity.java +++ b/src/com/android/gallery3d/filtershow/FilterShowActivity.java @@ -157,6 +157,7 @@ public class FilterShowActivity extends Activity implements OnItemClickListener, ImageShow.setDefaultBackgroundColor(getResources().getColor(R.color.background_screen)); ImageSmallFilter.setDefaultBackgroundColor(getResources().getColor(R.color.background_main_toolbar)); // TODO: get those values from XML. + ImageZoom.setZoomedSize(getPixelsFromDip(256)); FramedTextButton.setTextSize((int) getPixelsFromDip(14)); ImageShow.setTextSize((int) getPixelsFromDip(12)); ImageShow.setTextPadding((int) getPixelsFromDip(10)); diff --git a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java index b661aad1a..308e49c14 100644 --- a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java +++ b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java @@ -68,19 +68,20 @@ public class ImageLoader { private FilterShowActivity mActivity = null; - private static final int ORI_NORMAL = ExifInterface.ORIENTATION_NORMAL; - private static final int ORI_ROTATE_90 = ExifInterface.ORIENTATION_ROTATE_90; - private static final int ORI_ROTATE_180 = ExifInterface.ORIENTATION_ROTATE_180; - private static final int ORI_ROTATE_270 = ExifInterface.ORIENTATION_ROTATE_270; - private static final int ORI_FLIP_HOR = ExifInterface.ORIENTATION_FLIP_HORIZONTAL; - private static final int ORI_FLIP_VERT = ExifInterface.ORIENTATION_FLIP_VERTICAL; - private static final int ORI_TRANSPOSE = ExifInterface.ORIENTATION_TRANSPOSE; - private static final int ORI_TRANSVERSE = ExifInterface.ORIENTATION_TRANSVERSE; + public static final int ORI_NORMAL = ExifInterface.ORIENTATION_NORMAL; + public static final int ORI_ROTATE_90 = ExifInterface.ORIENTATION_ROTATE_90; + public static final int ORI_ROTATE_180 = ExifInterface.ORIENTATION_ROTATE_180; + public static final int ORI_ROTATE_270 = ExifInterface.ORIENTATION_ROTATE_270; + public static final int ORI_FLIP_HOR = ExifInterface.ORIENTATION_FLIP_HORIZONTAL; + public static final int ORI_FLIP_VERT = ExifInterface.ORIENTATION_FLIP_VERTICAL; + public static final int ORI_TRANSPOSE = ExifInterface.ORIENTATION_TRANSPOSE; + public static final int ORI_TRANSVERSE = ExifInterface.ORIENTATION_TRANSVERSE; private Context mContext = null; private Uri mUri = null; private Rect mOriginalBounds = null; + private static int mZoomOrientation = ORI_NORMAL; public ImageLoader(FilterShowActivity activity, Context context) { mActivity = activity; @@ -89,6 +90,10 @@ public class ImageLoader { mHiresCache = new DelayedPresetCache(this, 3); } + public static int getZoomOrientation() { + return mZoomOrientation; + } + public FilterShowActivity getActivity() { return mActivity; } @@ -170,6 +175,7 @@ public class ImageLoader { public static Bitmap rotateToPortrait(Bitmap bitmap,int ori) { Matrix matrix = new Matrix(); + mZoomOrientation = ori; int w = bitmap.getWidth(); int h = bitmap.getHeight(); if (ori == ORI_ROTATE_90 || diff --git a/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java b/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java index 77e78fe7d..a5ccbe0c7 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java +++ b/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java @@ -20,10 +20,9 @@ import android.graphics.Bitmap; import android.graphics.Matrix; import android.graphics.RectF; +import com.android.gallery3d.filtershow.cache.ImageLoader; import com.android.gallery3d.filtershow.filters.ImageFilterGeometry; -import java.util.Arrays; - public class GeometryMetadata { // Applied in order: rotate, crop, scale. // Do not scale saved image (presumably?). @@ -62,7 +61,7 @@ public class GeometryMetadata { if (!mCropBounds.equals(mPhotoBounds)) { return true; } - if (!mFlip.equals(FLIP.NONE)){ + if (!mFlip.equals(FLIP.NONE)) { return true; } return false; @@ -236,6 +235,99 @@ public class GeometryMetadata { } } + public Matrix getMatrixOriginalOrientation(int orientation, float originalWidth, + float originalHeight) { + Matrix imageRotation = new Matrix(); + switch (orientation) { + case ImageLoader.ORI_ROTATE_90: { + imageRotation.setRotate(90, originalWidth / 2f, originalHeight / 2f); + imageRotation.postTranslate(-(originalWidth - originalHeight) / 2f, + -(originalHeight - originalWidth) / 2f); + break; + } + case ImageLoader.ORI_ROTATE_180: { + imageRotation.setRotate(180, originalWidth / 2f, originalHeight / 2f); + break; + } + case ImageLoader.ORI_ROTATE_270: { + imageRotation.setRotate(270, originalWidth / 2f, originalHeight / 2f); + imageRotation.postTranslate(-(originalWidth - originalHeight) / 2f, + -(originalHeight - originalWidth) / 2f); + break; + } + case ImageLoader.ORI_FLIP_HOR: { + imageRotation.preScale(-1, 1); + break; + } + case ImageLoader.ORI_FLIP_VERT: { + imageRotation.preScale(1, -1); + break; + } + case ImageLoader.ORI_TRANSPOSE: { + imageRotation.setRotate(90, originalWidth / 2f, originalHeight / 2f); + imageRotation.postTranslate(-(originalWidth - originalHeight) / 2f, + -(originalHeight - originalWidth) / 2f); + imageRotation.preScale(1, -1); + break; + } + case ImageLoader.ORI_TRANSVERSE: { + imageRotation.setRotate(270, originalWidth / 2f, originalHeight / 2f); + imageRotation.postTranslate(-(originalWidth - originalHeight) / 2f, + -(originalHeight - originalWidth) / 2f); + imageRotation.preScale(1, -1); + break; + } + } + return imageRotation; + } + + public Matrix getOriginalToScreen(boolean rotate, float originalWidth, float originalHeight, + float viewWidth, float viewHeight) { + RectF photoBounds = getPhotoBounds(); + RectF cropBounds = getPreviewCropBounds(); + float imageWidth = cropBounds.width(); + float imageHeight = cropBounds.height(); + + int orientation = ImageLoader.getZoomOrientation(); + Matrix imageRotation = getMatrixOriginalOrientation(orientation, originalWidth, + originalHeight); + if (orientation == ImageLoader.ORI_ROTATE_90 || + orientation == ImageLoader.ORI_ROTATE_270 || + orientation == ImageLoader.ORI_TRANSPOSE || + orientation == ImageLoader.ORI_TRANSVERSE) { + float tmp = originalWidth; + originalWidth = originalHeight; + originalHeight = tmp; + } + + float preScale = GeometryMath.scale(originalWidth, originalHeight, + photoBounds.width(), photoBounds.height()); + float scale = GeometryMath.scale(imageWidth, imageHeight, viewWidth, viewHeight); + // checks if local rotation is an odd multiple of 90. + if (((int) (getRotation() / 90)) % 2 != 0) { + scale = GeometryMath.scale(imageWidth, imageHeight, viewHeight, viewWidth); + } + // put in screen coordinates + RectF scaledCrop = GeometryMath.scaleRect(cropBounds, scale); + RectF scaledPhoto = GeometryMath.scaleRect(photoBounds, scale); + float[] displayCenter = { + viewWidth / 2f, viewHeight / 2f + }; + Matrix m1 = GeometryMetadata.buildWanderingCropMatrix(scaledPhoto, scaledCrop, + getRotation(), getStraightenRotation(), getFlipType(), displayCenter); + float[] cropCenter = { + scaledCrop.centerX(), scaledCrop.centerY() + }; + m1.mapPoints(cropCenter); + GeometryMetadata.concatRecenterMatrix(m1, cropCenter, displayCenter); + m1.preRotate(getStraightenRotation(), scaledPhoto.centerX(), scaledPhoto.centerY()); + m1.preScale(scale, scale); + m1.preScale(preScale, preScale); + m1.preConcat(imageRotation); + + return m1; + } + // TODO: refactor away public Matrix getFlipMatrix(float width, float height) { FLIP type = getFlipType(); diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageZoom.java b/src/com/android/gallery3d/filtershow/imageshow/ImageZoom.java index e659e900a..c7586fe9b 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageZoom.java +++ b/src/com/android/gallery3d/filtershow/imageshow/ImageZoom.java @@ -19,14 +19,20 @@ package com.android.gallery3d.filtershow.imageshow; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.Matrix; import android.graphics.Rect; +import android.graphics.RectF; import android.util.AttributeSet; import android.view.MotionEvent; +import com.android.gallery3d.filtershow.cache.ImageLoader; + public class ImageZoom extends ImageSlave { + private static final String LOGTAG = "ImageZoom"; private boolean mTouchDown = false; private boolean mZoomedIn = false; private Rect mZoomBounds = null; + private static float mMaxSize = 512; public ImageZoom(Context context) { super(context); @@ -36,6 +42,17 @@ public class ImageZoom extends ImageSlave { super(context, attrs); } + public static void setZoomedSize(float size) { + mMaxSize = size; + } + + @Override + public void resetParameter() { + super.resetParameter(); + mZoomedIn = false; + mTouchDown = false; + } + @Override public void onTouchDown(float x, float y) { super.onTouchDown(x, y); @@ -43,23 +60,28 @@ public class ImageZoom extends ImageSlave { return; } mTouchDown = true; - Rect originalBounds = mImageLoader.getOriginalBounds(); - Rect imageBounds = getImageBounds(); - float touchX = x - imageBounds.left; - float touchY = y - imageBounds.top; - - float w = originalBounds.width(); - float h = originalBounds.height(); - float ratio = w / h; - int mw = getWidth() / 2; - int mh = getHeight() / 2; - int cx = (int) (w / 2); - int cy = (int) (h / 2); - cx = (int) (touchX / imageBounds.width() * w); - cy = (int) (touchY / imageBounds.height() * h); - int left = cx - mw; - int top = cy - mh; - mZoomBounds = new Rect(left, top, left + mw * 2, top + mh * 2); + GeometryMetadata geo = getImagePreset().mGeoData; + Matrix originalToScreen = geo.getOriginalToScreen(true, + mImageLoader.getOriginalBounds().width(), + mImageLoader.getOriginalBounds().height(), + getWidth(), getHeight()); + float[] point = new float[2]; + point[0] = x; + point[1] = y; + Matrix inverse = new Matrix(); + originalToScreen.invert(inverse); + inverse.mapPoints(point); + + float ratio = (float) getWidth() / (float) getHeight(); + float mh = mMaxSize; + float mw = ratio * mh; + RectF zoomRect = new RectF(mTouchX - mw, mTouchY - mh, mTouchX + mw, mTouchY + mw); + inverse.mapRect(zoomRect); + zoomRect.set(zoomRect.centerX() - mw, zoomRect.centerY() - mh, + zoomRect.centerX() + mw, zoomRect.centerY() + mh); + mZoomBounds = new Rect((int) zoomRect.left, (int) zoomRect.top, + (int) zoomRect.right, (int) zoomRect.bottom); + invalidate(); } @Override @@ -70,14 +92,42 @@ public class ImageZoom extends ImageSlave { @Override public void onDraw(Canvas canvas) { drawBackground(canvas); + Bitmap filteredImage = null; - if ((mZoomedIn ||mTouchDown) && mImageLoader != null) { - filteredImage = mImageLoader.getScaleOneImageForPreset(this, getImagePreset(), mZoomBounds, false); + if ((mZoomedIn || mTouchDown) && mImageLoader != null) { + filteredImage = mImageLoader.getScaleOneImageForPreset(this, getImagePreset(), + mZoomBounds, false); } else { requestFilteredImages(); filteredImage = getFilteredImage(); } + canvas.save(); + if (mZoomedIn || mTouchDown) { + int orientation = ImageLoader.getZoomOrientation(); + switch (orientation) { + case ImageLoader.ORI_ROTATE_90: { + canvas.rotate(90, getWidth() / 2, getHeight() / 2); + break; + } + case ImageLoader.ORI_ROTATE_270: { + canvas.rotate(270, getWidth() / 2, getHeight() / 2); + break; + } + case ImageLoader.ORI_TRANSPOSE: { + canvas.rotate(90, getWidth() / 2, getHeight() / 2); + canvas.scale(1, -1); + break; + } + case ImageLoader.ORI_TRANSVERSE: { + canvas.rotate(270, getWidth() / 2, getHeight() / 2); + canvas.scale(1, -1); + break; + } + } + } drawImage(canvas, filteredImage); + canvas.restore(); + if (showControls()) { mSliderController.onDraw(canvas); } @@ -97,4 +147,4 @@ public class ImageZoom extends ImageSlave { invalidate(); return false; } -} \ No newline at end of file +} -- cgit v1.2.3