OSDN Git Service

Moves matrix function to GeometryMetadata. Fixes scaling issues.
authorRuben Brunk <rubenbrunk@google.com>
Fri, 12 Oct 2012 09:03:18 +0000 (02:03 -0700)
committerRuben Brunk <rubenbrunk@google.com>
Fri, 12 Oct 2012 17:18:08 +0000 (10:18 -0700)
Bug:7337191
Change-Id: Icfd50c8a07ef02f2346a8ab7b57303de3866d74d

src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java
src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java
src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java

index 08c09fb..527800e 100644 (file)
@@ -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
index 0eb2e22..a14e065 100644 (file)
@@ -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);
     }
 }
index 98f892e..8da673b 100644 (file)
@@ -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);
         }
     }