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

Commit 8713a945 authored by Michael Jurka's avatar Michael Jurka
Browse files

Add EXIF rotation support to wallpaper picker

Bug: 11137824

Change-Id: I64e488207ffea219fca5ee00f47b98ccb2ac86d8
parent 982470ea
Loading
Loading
Loading
Loading
+89 −16
Original line number Original line Diff line number Diff line
@@ -17,9 +17,11 @@
package com.android.launcher3;
package com.android.launcher3;


import android.content.Context;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Point;
import android.graphics.RectF;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.OnScaleGestureListener;
import android.view.ScaleGestureDetector.OnScaleGestureListener;
@@ -36,10 +38,18 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
    private long mTouchDownTime;
    private long mTouchDownTime;
    private float mFirstX, mFirstY;
    private float mFirstX, mFirstY;
    private float mLastX, mLastY;
    private float mLastX, mLastY;
    private float mCenterX, mCenterY;
    private float mMinScale;
    private float mMinScale;
    private boolean mTouchEnabled = true;
    private boolean mTouchEnabled = true;
    private RectF mTempEdges = new RectF();
    private RectF mTempEdges = new RectF();
    private float[] mTempPoint = new float[] { 0, 0 };
    private float[] mTempCoef = new float[] { 0, 0 };
    private float[] mTempAdjustment = new float[] { 0, 0 };
    private float[] mTempImageDims = new float[] { 0, 0 };
    private float[] mTempRendererCenter = new float[] { 0, 0 };
    TouchCallback mTouchCallback;
    TouchCallback mTouchCallback;
    Matrix mRotateMatrix;
    Matrix mInverseRotateMatrix;


    public interface TouchCallback {
    public interface TouchCallback {
        void onTouchDown();
        void onTouchDown();
@@ -54,17 +64,43 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
    public CropView(Context context, AttributeSet attrs) {
    public CropView(Context context, AttributeSet attrs) {
        super(context, attrs);
        super(context, attrs);
        mScaleGestureDetector = new ScaleGestureDetector(context, this);
        mScaleGestureDetector = new ScaleGestureDetector(context, this);
        mRotateMatrix = new Matrix();
        mInverseRotateMatrix = new Matrix();
    }

    private float[] getImageDims() {
        final float imageWidth = mRenderer.source.getImageWidth();
        final float imageHeight = mRenderer.source.getImageHeight();
        float[] imageDims = mTempImageDims;
        imageDims[0] = imageWidth;
        imageDims[1] = imageHeight;
        mRotateMatrix.mapPoints(imageDims);
        imageDims[0] = Math.abs(imageDims[0]);
        imageDims[1] = Math.abs(imageDims[1]);
        return imageDims;
    }
    }


    private void getEdgesHelper(RectF edgesOut) {
    private void getEdgesHelper(RectF edgesOut) {
        final float width = getWidth();
        final float width = getWidth();
        final float height = getHeight();
        final float height = getHeight();
        final float imageWidth = mRenderer.source.getImageWidth();
        final float[] imageDims = getImageDims();
        final float imageHeight = mRenderer.source.getImageHeight();
        final float imageWidth = imageDims[0];
        final float imageHeight = imageDims[1];

        float initialCenterX = mRenderer.source.getImageWidth() / 2f;
        float initialCenterY = mRenderer.source.getImageHeight() / 2f;

        float[] rendererCenter = mTempRendererCenter;
        rendererCenter[0] = mCenterX - initialCenterX;
        rendererCenter[1] = mCenterY - initialCenterY;
        mRotateMatrix.mapPoints(rendererCenter);
        rendererCenter[0] += imageWidth / 2;
        rendererCenter[1] += imageHeight / 2;

        final float scale = mRenderer.scale;
        final float scale = mRenderer.scale;
        float centerX = (width / 2f - mRenderer.centerX + (imageWidth - width) / 2f)
        float centerX = (width / 2f - rendererCenter[0] + (imageWidth - width) / 2f)
                * scale + width / 2f;
                * scale + width / 2f;
        float centerY = (height / 2f - mRenderer.centerY + (imageHeight - height) / 2f)
        float centerY = (height / 2f - rendererCenter[1] + (imageHeight - height) / 2f)
                * scale + height / 2f;
                * scale + height / 2f;
        float leftEdge = centerX - imageWidth / 2f * scale;
        float leftEdge = centerX - imageWidth / 2f * scale;
        float rightEdge = centerX + imageWidth / 2f * scale;
        float rightEdge = centerX + imageWidth / 2f * scale;
@@ -77,6 +113,10 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
        edgesOut.bottom = bottomEdge;
        edgesOut.bottom = bottomEdge;
    }
    }


    public int getImageRotation() {
        return mRenderer.rotation;
    }

    public RectF getCrop() {
    public RectF getCrop() {
        final RectF edges = mTempEdges;
        final RectF edges = mTempEdges;
        getEdgesHelper(edges);
        getEdgesHelper(edges);
@@ -96,6 +136,12 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {


    public void setTileSource(TileSource source, Runnable isReadyCallback) {
    public void setTileSource(TileSource source, Runnable isReadyCallback) {
        super.setTileSource(source, isReadyCallback);
        super.setTileSource(source, isReadyCallback);
        mCenterX = mRenderer.centerX;
        mCenterY = mRenderer.centerY;
        mRotateMatrix.reset();
        mRotateMatrix.setRotate(mRenderer.rotation);
        mInverseRotateMatrix.reset();
        mInverseRotateMatrix.setRotate(-mRenderer.rotation);
        updateMinScale(getWidth(), getHeight(), source, true);
        updateMinScale(getWidth(), getHeight(), source, true);
    }
    }


@@ -115,8 +161,10 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
                mRenderer.scale = 1;
                mRenderer.scale = 1;
            }
            }
            if (source != null) {
            if (source != null) {
                mMinScale = Math.max(w / (float) source.getImageWidth(),
                final float[] imageDims = getImageDims();
                        h / (float) source.getImageHeight());
                final float imageWidth = imageDims[0];
                final float imageHeight = imageDims[1];
                mMinScale = Math.max(w / imageWidth, h / imageHeight);
                mRenderer.scale = Math.max(mMinScale, mRenderer.scale);
                mRenderer.scale = Math.max(mMinScale, mRenderer.scale);
            }
            }
        }
        }
@@ -154,7 +202,13 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
        final RectF edges = mTempEdges;
        final RectF edges = mTempEdges;
        getEdgesHelper(edges);
        getEdgesHelper(edges);
        final float scale = mRenderer.scale;
        final float scale = mRenderer.scale;
        mRenderer.centerX += Math.ceil(edges.left / scale);
        mCenterX += Math.ceil(edges.left / scale);
        updateCenter();
    }

    private void updateCenter() {
        mRenderer.centerX = Math.round(mCenterX);
        mRenderer.centerY = Math.round(mCenterY);
    }
    }


    public void setTouchEnabled(boolean enabled) {
    public void setTouchEnabled(boolean enabled) {
@@ -215,8 +269,13 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
            mScaleGestureDetector.onTouchEvent(event);
            mScaleGestureDetector.onTouchEvent(event);
            switch (action) {
            switch (action) {
                case MotionEvent.ACTION_MOVE:
                case MotionEvent.ACTION_MOVE:
                    mRenderer.centerX += (mLastX - x) / mRenderer.scale;
                    float[] point = mTempPoint;
                    mRenderer.centerY += (mLastY - y) / mRenderer.scale;
                    point[0] = (mLastX - x) / mRenderer.scale;
                    point[1] = (mLastY - y) / mRenderer.scale;
                    mInverseRotateMatrix.mapPoints(point);
                    mCenterX += point[0];
                    mCenterY += point[1];
                    updateCenter();
                    invalidate();
                    invalidate();
                    break;
                    break;
            }
            }
@@ -226,18 +285,32 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
                final RectF edges = mTempEdges;
                final RectF edges = mTempEdges;
                getEdgesHelper(edges);
                getEdgesHelper(edges);
                final float scale = mRenderer.scale;
                final float scale = mRenderer.scale;

                float[] coef = mTempCoef;
                coef[0] = 1;
                coef[1] = 1;
                mRotateMatrix.mapPoints(coef);
                float[] adjustment = mTempAdjustment;
                mTempAdjustment[0] = 0;
                mTempAdjustment[1] = 0;
                if (edges.left > 0) {
                if (edges.left > 0) {
                    mRenderer.centerX += Math.ceil(edges.left / scale);
                    adjustment[0] = edges.left / scale;
                }
                } else if (edges.right < getWidth()) {
                if (edges.right < getWidth()) {
                    adjustment[0] = (edges.right - getWidth()) / scale;
                    mRenderer.centerX += (edges.right - getWidth()) / scale;
                }
                }
                if (edges.top > 0) {
                if (edges.top > 0) {
                    mRenderer.centerY += Math.ceil(edges.top / scale);
                    adjustment[1] = FloatMath.ceil(edges.top / scale);
                } else if (edges.bottom < getHeight()) {
                    adjustment[1] = (edges.bottom - getHeight()) / scale;
                }
                }
                if (edges.bottom < getHeight()) {
                for (int dim = 0; dim <= 1; dim++) {
                    mRenderer.centerY += (edges.bottom - getHeight()) / scale;
                    if (coef[dim] > 0) adjustment[dim] = FloatMath.ceil(adjustment[dim]);
                }
                }

                mInverseRotateMatrix.mapPoints(adjustment);
                mCenterX += adjustment[0];
                mCenterY += adjustment[1];
                updateCenter();
            }
            }
        }
        }


+3 −1
Original line number Original line Diff line number Diff line
@@ -61,7 +61,9 @@ public class SavedWallpaperImages extends BaseAdapter implements ListAdapter {
            String imageFilename = a.getSavedImages().getImageFilename(mDbId);
            String imageFilename = a.getSavedImages().getImageFilename(mDbId);
            File file = new File(a.getFilesDir(), imageFilename);
            File file = new File(a.getFilesDir(), imageFilename);
            CropView v = a.getCropView();
            CropView v = a.getCropView();
            v.setTileSource(new BitmapRegionTileSource(a, file.getAbsolutePath(), 1024, 0), null);
            int rotation = WallpaperCropActivity.getRotationFromExif(file.getAbsolutePath());
            v.setTileSource(
                    new BitmapRegionTileSource(a, file.getAbsolutePath(), 1024, rotation), null);
            v.moveToLeft();
            v.moveToLeft();
            v.setTouchEnabled(false);
            v.setTouchEnabled(false);
        }
        }
+135 −39
Original line number Original line Diff line number Diff line
@@ -37,12 +37,14 @@ import android.graphics.RectF;
import android.net.Uri;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Bundle;
import android.util.FloatMath;
import android.util.Log;
import android.util.Log;
import android.view.Display;
import android.view.Display;
import android.view.View;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManager;


import com.android.gallery3d.common.Utils;
import com.android.gallery3d.common.Utils;
import com.android.gallery3d.exif.ExifInterface;
import com.android.photos.BitmapRegionTileSource;
import com.android.photos.BitmapRegionTileSource;


import java.io.BufferedInputStream;
import java.io.BufferedInputStream;
@@ -88,7 +90,8 @@ public class WallpaperCropActivity extends Activity {
        Intent cropIntent = this.getIntent();
        Intent cropIntent = this.getIntent();
        final Uri imageUri = cropIntent.getData();
        final Uri imageUri = cropIntent.getData();


        mCropView.setTileSource(new BitmapRegionTileSource(this, imageUri, 1024, 0), null);
        int rotation = getRotationFromExif(this, imageUri);
        mCropView.setTileSource(new BitmapRegionTileSource(this, imageUri, 1024, rotation), null);
        mCropView.setTouchEnabled(true);
        mCropView.setTouchEnabled(true);
        // Action bar
        // Action bar
        // Show the custom action bar view
        // Show the custom action bar view
@@ -168,9 +171,47 @@ public class WallpaperCropActivity extends Activity {
        return new Point(defaultWidth, defaultHeight);
        return new Point(defaultWidth, defaultHeight);
    }
    }


    public static int getRotationFromExif(String path) {
        return getRotationFromExifHelper(path, null, 0, null, null);
    }

    public static int getRotationFromExif(Context context, Uri uri) {
        return getRotationFromExifHelper(null, null, 0, context, uri);
    }

    public static int getRotationFromExif(Resources res, int resId) {
        return getRotationFromExifHelper(null, res, resId, null, null);
    }

    private static int getRotationFromExifHelper(
            String path, Resources res, int resId, Context context, Uri uri) {
        ExifInterface ei = new ExifInterface();
        try {
            if (path != null) {
                ei.readExif(path);
            } else if (uri != null) {
                InputStream is = context.getContentResolver().openInputStream(uri);
                BufferedInputStream bis = new BufferedInputStream(is);
                ei.readExif(bis);
            } else {
                InputStream is = res.openRawResource(resId);
                BufferedInputStream bis = new BufferedInputStream(is);
                ei.readExif(bis);
            }
            Integer ori = ei.getTagIntValue(ExifInterface.TAG_ORIENTATION);
            if (ori != null) {
                return ExifInterface.getRotationForOrientationValue(ori.shortValue());
            }
        } catch (IOException e) {
            Log.w(LOGTAG, "Getting exif data failed", e);
        }
        return 0;
    }

    protected void setWallpaper(String filePath, final boolean finishActivityWhenDone) {
    protected void setWallpaper(String filePath, final boolean finishActivityWhenDone) {
        BitmapCropTask cropTask = new BitmapCropTask(this,
        int rotation = getRotationFromExif(filePath);
                filePath, null, 0, 0, true, false, null);
        BitmapCropTask cropTask = new BitmapCropTask(
                this, filePath, null, rotation, 0, 0, true, false, null);
        final Point bounds = cropTask.getImageBounds();
        final Point bounds = cropTask.getImageBounds();
        Runnable onEndCrop = new Runnable() {
        Runnable onEndCrop = new Runnable() {
            public void run() {
            public void run() {
@@ -190,6 +231,7 @@ public class WallpaperCropActivity extends Activity {
            Resources res, int resId, final boolean finishActivityWhenDone) {
            Resources res, int resId, final boolean finishActivityWhenDone) {
        // crop this image and scale it down to the default wallpaper size for
        // crop this image and scale it down to the default wallpaper size for
        // this device
        // this device
        int rotation = getRotationFromExif(res, resId);
        Point inSize = mCropView.getSourceDimensions();
        Point inSize = mCropView.getSourceDimensions();
        Point outSize = getDefaultWallpaperSize(getResources(),
        Point outSize = getDefaultWallpaperSize(getResources(),
                getWindowManager());
                getWindowManager());
@@ -207,8 +249,7 @@ public class WallpaperCropActivity extends Activity {
            }
            }
        };
        };
        BitmapCropTask cropTask = new BitmapCropTask(this, res, resId,
        BitmapCropTask cropTask = new BitmapCropTask(this, res, resId,
                crop, outSize.x, outSize.y,
                crop, rotation, outSize.x, outSize.y, true, false, onEndCrop);
                true, false, onEndCrop);
        cropTask.execute();
        cropTask.execute();
    }
    }


@@ -220,8 +261,6 @@ public class WallpaperCropActivity extends Activity {
    protected void cropImageAndSetWallpaper(Uri uri,
    protected void cropImageAndSetWallpaper(Uri uri,
            OnBitmapCroppedHandler onBitmapCroppedHandler, final boolean finishActivityWhenDone) {
            OnBitmapCroppedHandler onBitmapCroppedHandler, final boolean finishActivityWhenDone) {
        // Get the crop
        // Get the crop
        Point inSize = mCropView.getSourceDimensions();

        boolean ltr = mCropView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
        boolean ltr = mCropView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;


        Point minDims = new Point();
        Point minDims = new Point();
@@ -260,12 +299,21 @@ public class WallpaperCropActivity extends Activity {
        }
        }
        // Get the crop
        // Get the crop
        RectF cropRect = mCropView.getCrop();
        RectF cropRect = mCropView.getCrop();
        int cropRotation = mCropView.getImageRotation();
        float cropScale = mCropView.getWidth() / (float) cropRect.width();
        float cropScale = mCropView.getWidth() / (float) cropRect.width();


        Point inSize = mCropView.getSourceDimensions();
        Matrix rotateMatrix = new Matrix();
        rotateMatrix.setRotate(cropRotation);
        float[] rotatedInSize = new float[] { inSize.x, inSize.y };
        rotateMatrix.mapPoints(rotatedInSize);
        rotatedInSize[0] = Math.abs(rotatedInSize[0]);
        rotatedInSize[1] = Math.abs(rotatedInSize[1]);

        // ADJUST CROP WIDTH
        // ADJUST CROP WIDTH
        // Extend the crop all the way to the right, for parallax
        // Extend the crop all the way to the right, for parallax
        // (or all the way to the left, in RTL)
        // (or all the way to the left, in RTL)
        float extraSpace = ltr ? inSize.x - cropRect.right : cropRect.left;
        float extraSpace = ltr ? rotatedInSize[0] - cropRect.right : cropRect.left;
        // Cap the amount of extra width
        // Cap the amount of extra width
        float maxExtraSpace = defaultWallpaperWidth / cropScale - cropRect.width();
        float maxExtraSpace = defaultWallpaperWidth / cropScale - cropRect.width();
        extraSpace = Math.min(extraSpace, maxExtraSpace);
        extraSpace = Math.min(extraSpace, maxExtraSpace);
@@ -283,7 +331,7 @@ public class WallpaperCropActivity extends Activity {
            float extraPortraitHeight =
            float extraPortraitHeight =
                    portraitHeight / cropScale - cropRect.height();
                    portraitHeight / cropScale - cropRect.height();
            float expandHeight =
            float expandHeight =
                    Math.min(Math.min(inSize.y - cropRect.bottom, cropRect.top),
                    Math.min(Math.min(rotatedInSize[1] - cropRect.bottom, cropRect.top),
                            extraPortraitHeight / 2);
                            extraPortraitHeight / 2);
            cropRect.top -= expandHeight;
            cropRect.top -= expandHeight;
            cropRect.bottom += expandHeight;
            cropRect.bottom += expandHeight;
@@ -301,7 +349,7 @@ public class WallpaperCropActivity extends Activity {
            }
            }
        };
        };
        BitmapCropTask cropTask = new BitmapCropTask(this, uri,
        BitmapCropTask cropTask = new BitmapCropTask(this, uri,
                cropRect, outWidth, outHeight, true, false, onEndCrop);
                cropRect, cropRotation, outWidth, outHeight, true, false, onEndCrop);
        if (onBitmapCroppedHandler != null) {
        if (onBitmapCroppedHandler != null) {
            cropTask.setOnBitmapCropped(onBitmapCroppedHandler);
            cropTask.setOnBitmapCropped(onBitmapCroppedHandler);
        }
        }
@@ -321,7 +369,7 @@ public class WallpaperCropActivity extends Activity {
        InputStream mInStream;
        InputStream mInStream;
        RectF mCropBounds = null;
        RectF mCropBounds = null;
        int mOutWidth, mOutHeight;
        int mOutWidth, mOutHeight;
        int mRotation = 0; // for now
        int mRotation;
        String mOutputFormat = "jpg"; // for now
        String mOutputFormat = "jpg"; // for now
        boolean mSetWallpaper;
        boolean mSetWallpaper;
        boolean mSaveCroppedBitmap;
        boolean mSaveCroppedBitmap;
@@ -332,40 +380,45 @@ public class WallpaperCropActivity extends Activity {
        boolean mNoCrop;
        boolean mNoCrop;


        public BitmapCropTask(Context c, String filePath,
        public BitmapCropTask(Context c, String filePath,
                RectF cropBounds, int outWidth, int outHeight,
                RectF cropBounds, int rotation, int outWidth, int outHeight,
                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
            mContext = c;
            mContext = c;
            mInFilePath = filePath;
            mInFilePath = filePath;
            init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
            init(cropBounds, rotation,
                    outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
        }
        }


        public BitmapCropTask(byte[] imageBytes,
        public BitmapCropTask(byte[] imageBytes,
                RectF cropBounds, int outWidth, int outHeight,
                RectF cropBounds, int rotation, int outWidth, int outHeight,
                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
            mInImageBytes = imageBytes;
            mInImageBytes = imageBytes;
            init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
            init(cropBounds, rotation,
                    outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
        }
        }


        public BitmapCropTask(Context c, Uri inUri,
        public BitmapCropTask(Context c, Uri inUri,
                RectF cropBounds, int outWidth, int outHeight,
                RectF cropBounds, int rotation, int outWidth, int outHeight,
                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
            mContext = c;
            mContext = c;
            mInUri = inUri;
            mInUri = inUri;
            init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
            init(cropBounds, rotation,
                    outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
        }
        }


        public BitmapCropTask(Context c, Resources res, int inResId,
        public BitmapCropTask(Context c, Resources res, int inResId,
                RectF cropBounds, int outWidth, int outHeight,
                RectF cropBounds, int rotation, int outWidth, int outHeight,
                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
            mContext = c;
            mContext = c;
            mInResId = inResId;
            mInResId = inResId;
            mResources = res;
            mResources = res;
            init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
            init(cropBounds, rotation,
                    outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
        }
        }


        private void init(RectF cropBounds, int outWidth, int outHeight,
        private void init(RectF cropBounds, int rotation, int outWidth, int outHeight,
                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
                boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
            mCropBounds = cropBounds;
            mCropBounds = cropBounds;
            mRotation = rotation;
            mOutWidth = outWidth;
            mOutWidth = outWidth;
            mOutHeight = outHeight;
            mOutHeight = outHeight;
            mSetWallpaper = setWallpaper;
            mSetWallpaper = setWallpaper;
@@ -452,6 +505,29 @@ public class WallpaperCropActivity extends Activity {
            if (mInStream != null) {
            if (mInStream != null) {
                // Find crop bounds (scaled to original image size)
                // Find crop bounds (scaled to original image size)
                Rect roundedTrueCrop = new Rect();
                Rect roundedTrueCrop = new Rect();
                Matrix rotateMatrix = new Matrix();
                Matrix inverseRotateMatrix = new Matrix();
                if (mRotation > 0) {
                    rotateMatrix.setRotate(mRotation);
                    inverseRotateMatrix.setRotate(-mRotation);

                    mCropBounds.roundOut(roundedTrueCrop);
                    mCropBounds = new RectF(roundedTrueCrop);

                    Point bounds = getImageBounds();

                    float[] rotatedBounds = new float[] { bounds.x, bounds.y };
                    rotateMatrix.mapPoints(rotatedBounds);
                    rotatedBounds[0] = Math.abs(rotatedBounds[0]);
                    rotatedBounds[1] = Math.abs(rotatedBounds[1]);

                    mCropBounds.offset(-rotatedBounds[0]/2, -rotatedBounds[1]/2);
                    inverseRotateMatrix.mapRect(mCropBounds);
                    mCropBounds.offset(bounds.x/2, bounds.y/2);

                    regenerateInputStream();
                }

                mCropBounds.roundOut(roundedTrueCrop);
                mCropBounds.roundOut(roundedTrueCrop);


                if (roundedTrueCrop.width() <= 0 || roundedTrueCrop.height() <= 0) {
                if (roundedTrueCrop.width() <= 0 || roundedTrueCrop.height() <= 0) {
@@ -495,6 +571,12 @@ public class WallpaperCropActivity extends Activity {
                        fullSize = BitmapFactory.decodeStream(mInStream, null, options);
                        fullSize = BitmapFactory.decodeStream(mInStream, null, options);
                    }
                    }
                    if (fullSize != null) {
                    if (fullSize != null) {
                        mCropBounds.left /= scaleDownSampleSize;
                        mCropBounds.top /= scaleDownSampleSize;
                        mCropBounds.bottom /= scaleDownSampleSize;
                        mCropBounds.right /= scaleDownSampleSize;
                        mCropBounds.roundOut(roundedTrueCrop);

                        crop = Bitmap.createBitmap(fullSize, roundedTrueCrop.left,
                        crop = Bitmap.createBitmap(fullSize, roundedTrueCrop.left,
                                roundedTrueCrop.top, roundedTrueCrop.width(),
                                roundedTrueCrop.top, roundedTrueCrop.width(),
                                roundedTrueCrop.height());
                                roundedTrueCrop.height());
@@ -506,16 +588,40 @@ public class WallpaperCropActivity extends Activity {
                    failure = true;
                    failure = true;
                    return false;
                    return false;
                }
                }
                if (mOutWidth > 0 && mOutHeight > 0) {
                if (mOutWidth > 0 && mOutHeight > 0 || mRotation > 0) {
                    Matrix m = new Matrix();
                    float[] dimsAfter = new float[] { crop.getWidth(), crop.getHeight() };
                    RectF cropRect = new RectF(0, 0, crop.getWidth(), crop.getHeight());
                    rotateMatrix.mapPoints(dimsAfter);
                    if (mRotation > 0) {
                    dimsAfter[0] = Math.abs(dimsAfter[0]);
                        m.setRotate(mRotation);
                    dimsAfter[1] = Math.abs(dimsAfter[1]);
                        m.mapRect(cropRect);

                    if (!(mOutWidth > 0 && mOutHeight > 0)) {
                        mOutWidth = Math.round(dimsAfter[0]);
                        mOutHeight = Math.round(dimsAfter[1]);
                    }
                    }

                    RectF cropRect = new RectF(0, 0, dimsAfter[0], dimsAfter[1]);
                    RectF returnRect = new RectF(0, 0, mOutWidth, mOutHeight);
                    RectF returnRect = new RectF(0, 0, mOutWidth, mOutHeight);

                    Matrix m = new Matrix();
                    if (mRotation == 0) {
                        m.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL);
                        m.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL);
                    m.preRotate(mRotation);
                    } else {
                        Matrix m1 = new Matrix();
                        m1.setTranslate(-crop.getWidth() / 2f, -crop.getHeight() / 2f);
                        Matrix m2 = new Matrix();
                        m2.setRotate(mRotation);
                        Matrix m3 = new Matrix();
                        m3.setTranslate(dimsAfter[0] / 2f, dimsAfter[1] / 2f);
                        Matrix m4 = new Matrix();
                        m4.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL);

                        Matrix c1 = new Matrix();
                        c1.setConcat(m2, m1);
                        Matrix c2 = new Matrix();
                        c2.setConcat(m4, m3);
                        m.setConcat(c2, c1);
                    }

                    Bitmap tmp = Bitmap.createBitmap((int) returnRect.width(),
                    Bitmap tmp = Bitmap.createBitmap((int) returnRect.width(),
                            (int) returnRect.height(), Bitmap.Config.ARGB_8888);
                            (int) returnRect.height(), Bitmap.Config.ARGB_8888);
                    if (tmp != null) {
                    if (tmp != null) {
@@ -525,14 +631,6 @@ public class WallpaperCropActivity extends Activity {
                        c.drawBitmap(crop, m, p);
                        c.drawBitmap(crop, m, p);
                        crop = tmp;
                        crop = tmp;
                    }
                    }
                } else if (mRotation > 0) {
                    Matrix m = new Matrix();
                    m.setRotate(mRotation);
                    Bitmap tmp = Bitmap.createBitmap(crop, 0, 0, crop.getWidth(),
                            crop.getHeight(), m, true);
                    if (tmp != null) {
                        crop = tmp;
                    }
                }
                }


                if (mSaveCroppedBitmap) {
                if (mSaveCroppedBitmap) {
@@ -601,8 +699,7 @@ public class WallpaperCropActivity extends Activity {
            final SharedPreferences sharedPrefs,
            final SharedPreferences sharedPrefs,
            WindowManager windowManager,
            WindowManager windowManager,
            final WallpaperManager wallpaperManager) {
            final WallpaperManager wallpaperManager) {
        final Point defaultWallpaperSize =
        final Point defaultWallpaperSize = getDefaultWallpaperSize(res, windowManager);
                WallpaperCropActivity.getDefaultWallpaperSize(res, windowManager);


        new Thread("suggestWallpaperDimension") {
        new Thread("suggestWallpaperDimension") {
            public void run() {
            public void run() {
@@ -614,7 +711,6 @@ public class WallpaperCropActivity extends Activity {
        }.start();
        }.start();
    }
    }



    protected static RectF getMaxCropRect(
    protected static RectF getMaxCropRect(
            int inWidth, int inHeight, int outWidth, int outHeight, boolean leftAligned) {
            int inWidth, int inHeight, int outWidth, int outHeight, boolean leftAligned) {
        RectF cropRect = new RectF();
        RectF cropRect = new RectF();
+34 −16

File changed.

Preview size limit exceeded, changes collapsed.

+1 −1
Original line number Original line Diff line number Diff line
@@ -63,7 +63,7 @@ public class TiledImageView extends FrameLayout {
        // Guarded by locks
        // Guarded by locks
        public float scale;
        public float scale;
        public int centerX, centerY;
        public int centerX, centerY;
        int rotation;
        public int rotation;
        public TileSource source;
        public TileSource source;
        Runnable isReadyCallback;
        Runnable isReadyCallback;