diff options
author | Ruben Brunk <rubenbrunk@google.com> | 2012-10-12 02:03:18 -0700 |
---|---|---|
committer | Ruben Brunk <rubenbrunk@google.com> | 2012-10-12 10:18:08 -0700 |
commit | 98de2e2ff9ab7959ee7d6035a9f87ed39ebc7537 (patch) | |
tree | ac19b61bb1516d6778002874e030f756761c20f6 | |
parent | f392c6598fd98d3e79583c827809f227071c8269 (diff) | |
download | android_packages_apps_Snap-98de2e2ff9ab7959ee7d6035a9f87ed39ebc7537.tar.gz android_packages_apps_Snap-98de2e2ff9ab7959ee7d6035a9f87ed39ebc7537.tar.bz2 android_packages_apps_Snap-98de2e2ff9ab7959ee7d6035a9f87ed39ebc7537.zip |
Moves matrix function to GeometryMetadata. Fixes scaling issues.
Bug:7337191
Change-Id: Icfd50c8a07ef02f2346a8ab7b57303de3866d74d
3 files changed, 59 insertions, 114 deletions
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java index 08c09fb8e..527800e13 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java @@ -62,22 +62,15 @@ public class ImageFilterGeometry extends ImageFilter { Bitmap dst, int dstWidth, int dstHeight, float straightenAngle); public Matrix buildMatrix(Bitmap bitmap, boolean rotated) { - Matrix drawMatrix = new Matrix(); - float dx = bitmap.getWidth() / 2.0f; - float dy = bitmap.getHeight() / 2.0f; - - Matrix flipper = mGeometry.getFlipMatrix(bitmap.getWidth(), bitmap.getHeight()); - drawMatrix.postConcat(flipper); - drawMatrix.postTranslate(-dx, -dy); - drawMatrix.postScale(1.0f / mGeometry.getScaleFactor(), 1.0f / mGeometry.getScaleFactor()); - float angle = (mGeometry.getRotation() + mGeometry.getStraightenRotation()); - drawMatrix.postRotate(angle); - if (rotated) { - drawMatrix.postTranslate(dy, dx); - } else { - drawMatrix.postTranslate(dx, dy); + float dx = bitmap.getWidth()/2; + float dy = bitmap.getHeight()/2; + if(mGeometry.hasSwitchedWidthHeight()){ + float temp = dx; + dx = dy; + dy = temp; } - return drawMatrix; + Matrix m = mGeometry.buildGeometryMatrix(bitmap.getWidth(), bitmap.getHeight(), 1f/mGeometry.getScaleFactor(), dx, dy); + return m; } @Override diff --git a/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java b/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java index 0eb2e22aa..a14e065b2 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java +++ b/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java @@ -22,13 +22,6 @@ import android.graphics.RectF; import com.android.gallery3d.filtershow.filters.ImageFilterGeometry; -/** - * This class holds metadata about an image's geometry. Specifically: rotation, - * scaling, cropping, and image boundaries. It maintains the invariant that the - * cropping boundaries are within or equal to the image boundaries (before - * rotation) WHEN mSafe is true. - */ - public class GeometryMetadata { // Applied in order: rotate, crop, scale. // Do not scale saved image (presumably?). @@ -39,9 +32,7 @@ public class GeometryMetadata { private final RectF mCropBounds = new RectF(); private final RectF mPhotoBounds = new RectF(); private FLIP mFlip = FLIP.NONE; - private boolean mSafe = false; - private Matrix mMatrix = new Matrix(); private RectF mBounds = new RectF(); @@ -62,7 +53,6 @@ public class GeometryMetadata { return m; } - // Safe as long as invariant holds. public void set(GeometryMetadata g) { mScaleFactor = g.mScaleFactor; mRotation = g.mRotation; @@ -70,8 +60,6 @@ public class GeometryMetadata { mCropBounds.set(g.mCropBounds); mPhotoBounds.set(g.mPhotoBounds); mFlip = g.mFlip; - mSafe = g.mSafe; - mMatrix = g.mMatrix; mBounds = g.mBounds; } @@ -99,9 +87,6 @@ public class GeometryMetadata { return new RectF(mPhotoBounds); } - public boolean safe() { - return mSafe; - } public void setScaleFactor(float scale) { mScaleFactor = scale; @@ -119,41 +104,12 @@ public class GeometryMetadata { mStraightenRotation = straighten; } - /** - * Sets crop bounds to be the intersection of mPhotoBounds and the new crop - * bounds. If there was no intersection, returns false and does not set crop - * bounds - */ - public boolean safeSetCropBounds(RectF newCropBounds) { - if (mCropBounds.setIntersect(newCropBounds, mPhotoBounds)) { - mSafe = true; - return true; - } - return false; - } - public void setCropBounds(RectF newCropBounds) { mCropBounds.set(newCropBounds); - mSafe = false; - } - - /** - * Sets mPhotoBounds to be the new photo bounds and sets mCropBounds to be - * the intersection of the new photo bounds and the old crop bounds. Sets - * the crop bounds to mPhotoBounds if there is no intersection. - */ - - public void safeSetPhotoBounds(RectF newPhotoBounds) { - mPhotoBounds.set(newPhotoBounds); - if (!mCropBounds.intersect(mPhotoBounds)) { - mCropBounds.set(mPhotoBounds); - } - mSafe = true; } public void setPhotoBounds(RectF newPhotoBounds) { mPhotoBounds.set(newPhotoBounds); - mSafe = false; } public boolean cropFitsInPhoto(RectF cropBounds) { @@ -171,7 +127,7 @@ public class GeometryMetadata { return (mScaleFactor == d.mScaleFactor && mRotation == d.mRotation && mStraightenRotation == d.mStraightenRotation && - mFlip == d.mFlip && mSafe == d.mSafe && + mFlip == d.mFlip && mCropBounds.equals(d.mCropBounds) && mPhotoBounds.equals(d.mPhotoBounds)); } @@ -184,15 +140,13 @@ public class GeometryMetadata { result = 31 * result + mFlip.hashCode(); result = 31 * result + mCropBounds.hashCode(); result = 31 * result + mPhotoBounds.hashCode(); - result = 31 * result + (mSafe ? 1 : 0); return result; } @Override public String toString() { return getClass().getName() + "[" + "scale=" + mScaleFactor - + ",rotation=" + mRotation + ",flip=" + mFlip + ",safe=" - + (mSafe ? "true" : "false") + ",straighten=" + + ",rotation=" + mRotation + ",flip=" + mFlip + ",straighten=" + mStraightenRotation + ",cropRect=" + mCropBounds.toShortString() + ",photoRect=" + mPhotoBounds.toShortString() + "]"; } @@ -228,7 +182,27 @@ public class GeometryMetadata { } } - public Matrix getMatrix() { - return mMatrix; + public boolean hasSwitchedWidthHeight(){ + return (((int) (mRotation / 90)) % 2) != 0; + } + + public Matrix buildGeometryMatrix(float width, float height, float scaling, float dx, float dy){ + float dx0 = width/2; + float dy0 = height/2; + Matrix m = getFlipMatrix(width, height); + m.postTranslate(-dx0, -dy0); + float rot = mRotation % 360; + if (rot < 0) + rot += 360; + m.postRotate(rot + mStraightenRotation); + m.postScale(scaling, scaling); + m.postTranslate(dx, dy); + return m; + } + + public Matrix buildGeometryUIMatrix(float scaling, float dx, float dy){ + float w = mPhotoBounds.width(); + float h = mPhotoBounds.height(); + return buildGeometryMatrix(w, h, scaling, dx, dy); } } diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java b/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java index 98f892e8c..8da673ba6 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java +++ b/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java @@ -48,8 +48,6 @@ public abstract class ImageGeometry extends ImageSlave { protected float mTouchCenterX; protected float mTouchCenterY; - private Matrix mLocalMatrix = null; - // Local geometry data private GeometryMetadata mLocalGeoMetadata = null; private RectF mLocalDisplayBounds = null; @@ -100,9 +98,6 @@ public abstract class ImageGeometry extends ImageSlave { mCenterY = displayHeight / 2; mYOffset = (displayHeight - imageHeight) / 2.0f; mXOffset = (displayWidth - imageWidth) / 2.0f; - - float zoom = computeScale(mLocalDisplayBounds.width(), mLocalDisplayBounds.height()); - mLocalGeoMetadata.setScaleFactor(zoom); } @Override @@ -120,11 +115,6 @@ public abstract class ImageGeometry extends ImageSlave { protected void syncLocalToMasterGeometry() { mLocalGeoMetadata = getMaster().getGeometry(); calculateLocalScalingFactorAndOffset(); - mLocalMatrix = mLocalGeoMetadata.getMatrix(); - } - - public Matrix getLocalMatrix() { - return mLocalMatrix; } protected RectF getLocalPhotoBounds() { @@ -155,31 +145,25 @@ public abstract class ImageGeometry extends ImageSlave { mLocalGeoMetadata.setScaleFactor(s); } - protected void updateMatrix() { + protected void updateScale(){ RectF bounds = getUntranslatedStraightenCropBounds(mLocalGeoMetadata.getPhotoBounds(), getLocalStraighten()); float zoom = computeScale(bounds.width(), bounds.height()); setLocalScale(zoom); - float w = mLocalGeoMetadata.getPhotoBounds().width(); - float h = mLocalGeoMetadata.getPhotoBounds().height(); - float ratio = h / w; - float rcenterx = 0.5f; - float rcentery = 0.5f * ratio; - Matrix flipper = mLocalGeoMetadata.getFlipMatrix(1.0f, ratio); - mLocalMatrix.reset(); - mLocalMatrix.postConcat(flipper); - mLocalMatrix.postRotate(getTotalLocalRotation(), rcenterx, rcentery); - invalidate(); } protected void setLocalRotation(float r) { mLocalGeoMetadata.setRotation(r); - updateMatrix(); + updateScale(); + } + + private Matrix getLocalGeoMatrix(float scaling, float dx, float dy) { + return mLocalGeoMetadata.buildGeometryUIMatrix(scaling, dx, dy); } protected void setLocalStraighten(float r) { mLocalGeoMetadata.setStraightenRotation(r); - updateMatrix(); + updateScale(); } protected void setLocalCropBounds(RectF c) { @@ -192,7 +176,6 @@ public abstract class ImageGeometry extends ImageSlave { protected void setLocalFlip(FLIP flip) { mLocalGeoMetadata.setFlipType(flip); - updateMatrix(); } protected float getTotalLocalRotation() { @@ -223,11 +206,8 @@ public abstract class ImageGeometry extends ImageSlave { // Returns maximal rectangular crop bound that still fits within // the image bound after the image has been rotated. - protected static RectF findCropBoundForRotatedImg(RectF cropBound, - RectF imageBound, - float rotation, - float centerX, - float centerY) { + protected static RectF findCropBoundForRotatedImg(RectF cropBound, RectF imageBound, + float rotation, float centerX, float centerY) { Matrix m = new Matrix(); float[] cropEdges = getCornersFromRect(cropBound); m.setRotate(rotation, centerX, centerY); @@ -310,10 +290,6 @@ public abstract class ImageGeometry extends ImageSlave { return height * w / h; } - protected void logMasterGeo() { - Log.v(LOGTAG, getMaster().getGeometry().toString()); - } - @Override protected void onVisibilityChanged(View changedView, int visibility) { super.onVisibilityChanged(changedView, visibility); @@ -321,11 +297,9 @@ public abstract class ImageGeometry extends ImageSlave { mVisibilityGained = true; syncLocalToMasterGeometry(); gainedVisibility(); - logMasterGeo(); } else { if (mVisibilityGained == true && mHasDrawn == true) { lostVisibility(); - logMasterGeo(); } mVisibilityGained = false; mHasDrawn = false; @@ -334,7 +308,7 @@ public abstract class ImageGeometry extends ImageSlave { protected void gainedVisibility() { // TODO: Override this stub. - updateMatrix(); + updateScale(); } protected void lostVisibility() { @@ -357,7 +331,6 @@ public abstract class ImageGeometry extends ImageSlave { setActionUp(); saveAndSetPreset(); Log.v(LOGTAG, "up action"); - logMasterGeo(); break; case (MotionEvent.ACTION_MOVE): setActionMove(event.getX(), event.getY()); @@ -457,10 +430,14 @@ public abstract class ImageGeometry extends ImageSlave { } public Matrix computeBoundsMatrix(Bitmap bitmap) { + float w = getWidth(); + float h = getHeight(); Matrix boundsMatrix = new Matrix(); boundsMatrix.setTranslate((getWidth() - bitmap.getWidth()) / 2.0f, (getHeight() - bitmap.getHeight()) / 2.0f); boundsMatrix.postRotate(getLocalRotation(), getWidth() / 2.0f, getHeight() / 2.0f); + float scale = computeScale(w, h); + boundsMatrix.postScale(scale, scale, getWidth()/2, getHeight()/2); return boundsMatrix; } @@ -473,26 +450,27 @@ public abstract class ImageGeometry extends ImageSlave { return transformedBounds; } + protected void drawImage(Canvas canvas, Bitmap bitmap, Paint paint) { + float scale = computeScale(getWidth(), getHeight()); + float yoff = getHeight()/2; + float xoff = getWidth()/2; + Matrix m = getLocalGeoMatrix(scale, xoff, yoff); + canvas.save(); + canvas.drawBitmap(bitmap, m, paint); + } + protected void drawTransformedBitmap(Canvas canvas, Bitmap bitmap, Paint paint, boolean clip) { + float w = getWidth(); + float h = getHeight(); Matrix boundsMatrix = computeBoundsMatrix(bitmap); RectF bounds = getUntranslatedStraightenCropBounds(getLocalPhotoBounds(), getLocalStraighten()); RectF transformedBounds = new RectF(bounds); boundsMatrix.mapRect(transformedBounds); - canvas.save(); - Matrix matrix = getLocalMatrix(); - canvas.translate((getWidth() - bitmap.getWidth()) / 2.0f, - (getHeight() - bitmap.getHeight()) / 2.0f); paint.setARGB(255, 0, 0, 0); - Matrix drawMatrix = new Matrix(); - float w = bitmap.getWidth(); - drawMatrix.preScale(1.0f/w, 1.0f/w); - drawMatrix.postConcat(matrix); - drawMatrix.postScale(w, w); - canvas.drawBitmap(bitmap, drawMatrix, paint); + drawImage(canvas, bitmap, paint); canvas.restore(); - canvas.save(); canvas.setMatrix(boundsMatrix); paint.setColor(Color.WHITE); @@ -502,7 +480,7 @@ public abstract class ImageGeometry extends ImageSlave { canvas.restore(); if (!clip) { // we display the rest of the bitmap grayed-out - drawShadows(canvas, transformedBounds, new RectF(0, 0, getWidth(), getHeight()), paint); + drawShadows(canvas, transformedBounds, new RectF(0, 0, w, h), paint); } } |