Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 46163a39 authored by Ruben Brunk's avatar Ruben Brunk
Browse files

Moves matrix function to GeometryMetadata. Fixes scaling issues.

Bug:7337191
Change-Id: Icfd50c8a07ef02f2346a8ab7b57303de3866d74d
parent 808dbe19
Loading
Loading
Loading
Loading
+8 −15
Original line number Diff line number Diff line
@@ -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
+24 −50
Original line number Diff line number Diff line
@@ -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);
    }
}
+27 −49
Original line number Diff line number Diff line
@@ -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);
        }
    }