18537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk/* 28537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk * Copyright (C) 2012 The Android Open Source Project 38537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk * 48537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk * Licensed under the Apache License, Version 2.0 (the "License"); 58537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk * you may not use this file except in compliance with the License. 68537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk * You may obtain a copy of the License at 78537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk * 88537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk * http://www.apache.org/licenses/LICENSE-2.0 98537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk * 108537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk * Unless required by applicable law or agreed to in writing, software 118537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk * distributed under the License is distributed on an "AS IS" BASIS, 128537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk * See the License for the specific language governing permissions and 148537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk * limitations under the License. 158537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk */ 160d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard 170d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroardpackage com.android.gallery3d.filtershow.imageshow; 180d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard 197a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroardimport android.animation.ValueAnimator; 200d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroardimport android.content.Context; 210d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroardimport android.graphics.Bitmap; 220d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroardimport android.graphics.Canvas; 23b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunkimport android.graphics.Color; 24b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunkimport android.graphics.Matrix; 250d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroardimport android.graphics.Paint; 26b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunkimport android.graphics.Paint.Style; 27b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunkimport android.graphics.Path; 280d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroardimport android.graphics.RectF; 290d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroardimport android.util.AttributeSet; 30b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunkimport android.view.MotionEvent; 3192e2341248e99c691f38820503984bc5e2f18811nicolasroard 32805a7fe57da2534462f4720abc7fe9cdb8f7ecc9John Hofordimport com.android.gallery3d.filtershow.crop.CropDrawingUtils; 33d61a2f9fcaad0309132b6b9b666c3dc6df62fed7John Hofordimport com.android.gallery3d.filtershow.editors.EditorStraighten; 34b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunkimport com.android.gallery3d.filtershow.filters.FilterCropRepresentation; 35b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunkimport com.android.gallery3d.filtershow.filters.FilterRepresentation; 36b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunkimport com.android.gallery3d.filtershow.filters.FilterStraightenRepresentation; 37b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunkimport com.android.gallery3d.filtershow.imageshow.GeometryMathUtils.GeometryHolder; 380a32b7afc5286a5c7aa334b9338591d61a49731fRuben Brunk 39b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunkimport java.util.ArrayList; 40b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunkimport java.util.Collection; 410d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard 42b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk 43b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunkpublic class ImageStraighten extends ImageShow { 44b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private static final String TAG = ImageStraighten.class.getSimpleName(); 450d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard private float mBaseAngle = 0; 460d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard private float mAngle = 0; 47b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private float mInitialAngle = 0; 48805a7fe57da2534462f4720abc7fe9cdb8f7ecc9John Hoford private static final int NBLINES = 16; 49b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private boolean mFirstDrawSinceUp = false; 50d61a2f9fcaad0309132b6b9b666c3dc6df62fed7John Hoford private EditorStraighten mEditorStraighten; 51b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private FilterStraightenRepresentation mLocalRep = new FilterStraightenRepresentation(); 52b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private RectF mPriorCropAtUp = new RectF(); 53b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private RectF mDrawRect = new RectF(); 54b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private Path mDrawPath = new Path(); 55b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private GeometryHolder mDrawHolder = new GeometryHolder(); 56b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private enum MODES { 57b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk NONE, MOVE 58b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk } 59b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private MODES mState = MODES.NONE; 607a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard private ValueAnimator mAnimator = null; 617a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard private int mDefaultGridAlpha = 60; 627a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard private float mGridAlpha = 1f; 637a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard private int mOnStartAnimDelay = 1000; 647a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard private int mAnimDelay = 500; 65b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private static final float MAX_STRAIGHTEN_ANGLE 66b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk = FilterStraightenRepresentation.MAX_STRAIGHTEN_ANGLE; 67b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private static final float MIN_STRAIGHTEN_ANGLE 68b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk = FilterStraightenRepresentation.MIN_STRAIGHTEN_ANGLE; 69b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private float mCurrentX; 70b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private float mCurrentY; 71b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private float mTouchCenterX; 72b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private float mTouchCenterY; 73b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private RectF mCrop = new RectF(); 74b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private final Paint mPaint = new Paint(); 750d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard 760d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard public ImageStraighten(Context context) { 770d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard super(context); 780d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard } 790d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard 800d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard public ImageStraighten(Context context, AttributeSet attrs) { 810d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard super(context, attrs); 820d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard } 830d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard 847a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard @Override 857a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard public void attach() { 867a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard super.attach(); 877a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard mGridAlpha = 1f; 887a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard hidesGrid(mOnStartAnimDelay); 897a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard } 907a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard 917a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard private void hidesGrid(int delay) { 927a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard mAnimator = ValueAnimator.ofFloat(1, 0); 937a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard mAnimator.setStartDelay(delay); 947a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard mAnimator.setDuration(mAnimDelay); 957a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 967a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard @Override 977a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard public void onAnimationUpdate(ValueAnimator animation) { 987a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard mGridAlpha = ((Float) animation.getAnimatedValue()); 997a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard invalidate(); 1007a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard } 1017a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard }); 1027a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard mAnimator.start(); 1037a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard } 1047a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard 105b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk public void setFilterStraightenRepresentation(FilterStraightenRepresentation rep) { 106b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mLocalRep = (rep == null) ? new FilterStraightenRepresentation() : rep; 107b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mInitialAngle = mBaseAngle = mAngle = mLocalRep.getStraighten(); 10892e2341248e99c691f38820503984bc5e2f18811nicolasroard } 10992e2341248e99c691f38820503984bc5e2f18811nicolasroard 110b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk public Collection<FilterRepresentation> getFinalRepresentation() { 111b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk ArrayList<FilterRepresentation> reps = new ArrayList<FilterRepresentation>(2); 112b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk reps.add(mLocalRep); 113b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk if (mInitialAngle != mLocalRep.getStraighten()) { 114b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk reps.add(new FilterCropRepresentation(mCrop)); 115b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk } 116b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk return reps; 11762e962bcb9fc03f3cfeac5ece8d3e95fc2dd0718Ruben Brunk } 11862e962bcb9fc03f3cfeac5ece8d3e95fc2dd0718Ruben Brunk 11992e2341248e99c691f38820503984bc5e2f18811nicolasroard @Override 120b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk public boolean onTouchEvent(MotionEvent event) { 121b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk float x = event.getX(); 122b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk float y = event.getY(); 123b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk 124b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk switch (event.getActionMasked()) { 125b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk case (MotionEvent.ACTION_DOWN): 126b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk if (mState == MODES.NONE) { 127b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mTouchCenterX = x; 128b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mTouchCenterY = y; 129b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mCurrentX = x; 130b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mCurrentY = y; 131b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mState = MODES.MOVE; 132b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mBaseAngle = mAngle; 133b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk } 134b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk break; 135b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk case (MotionEvent.ACTION_UP): 136b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk if (mState == MODES.MOVE) { 137b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mState = MODES.NONE; 138b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mCurrentX = x; 139b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mCurrentY = y; 140b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk computeValue(); 141b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mFirstDrawSinceUp = true; 1427a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard hidesGrid(0); 143b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk } 144b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk break; 145b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk case (MotionEvent.ACTION_MOVE): 146b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk if (mState == MODES.MOVE) { 147b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mCurrentX = x; 148b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mCurrentY = y; 149b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk computeValue(); 150b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk } 151b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk break; 152b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk default: 153b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk break; 154b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk } 155b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk invalidate(); 156b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk return true; 157b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk } 158b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk 159b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private static float angleFor(float dx, float dy) { 160b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk return (float) (Math.atan2(dx, dy) * 180 / Math.PI); 161b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk } 162b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk 163b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private float getCurrentTouchAngle() { 164b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk float centerX = getWidth() / 2f; 165b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk float centerY = getHeight() / 2f; 166b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk if (mCurrentX == mTouchCenterX && mCurrentY == mTouchCenterY) { 167b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk return 0; 168b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk } 169b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk float dX1 = mTouchCenterX - centerX; 170b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk float dY1 = mTouchCenterY - centerY; 171b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk float dX2 = mCurrentX - centerX; 172b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk float dY2 = mCurrentY - centerY; 173b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk float angleA = angleFor(dX1, dY1); 174b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk float angleB = angleFor(dX2, dY2); 175b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk return (angleB - angleA) % 360; 1760d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard } 1770d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard 1780d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard private void computeValue() { 1790f7dc6ef6e736c0993240450b50b91721c79c43eRuben Brunk float angle = getCurrentTouchAngle(); 1800d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard mAngle = (mBaseAngle - angle) % 360; 1818537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk mAngle = Math.max(MIN_STRAIGHTEN_ANGLE, mAngle); 1828537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk mAngle = Math.min(MAX_STRAIGHTEN_ANGLE, mAngle); 1830d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard } 1840d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard 185430e46b06f8e7ee1ca3e7ecdcef3e0a978637c03nicolasroard public static void getUntranslatedStraightenCropBounds(RectF outRect, float straightenAngle) { 186b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk float deg = straightenAngle; 187b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk if (deg < 0) { 188b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk deg = -deg; 189b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk } 190b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk double a = Math.toRadians(deg); 191b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk double sina = Math.sin(a); 192b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk double cosa = Math.cos(a); 193b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk double rw = outRect.width(); 194b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk double rh = outRect.height(); 195b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk double h1 = rh * rh / (rw * sina + rh * cosa); 196b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk double h2 = rh * rw / (rw * cosa + rh * sina); 197b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk double hh = Math.min(h1, h2); 198b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk double ww = hh * rw / rh; 199b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk float left = (float) ((rw - ww) * 0.5f); 200b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk float top = (float) ((rh - hh) * 0.5f); 201b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk float right = (float) (left + ww); 202b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk float bottom = (float) (top + hh); 203b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk outRect.set(left, top, right, bottom); 2048537d097f8827caedc8c39564de54d36eae8b16fRuben Brunk } 2050d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard 206b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk private void updateCurrentCrop(Matrix m, GeometryHolder h, RectF tmp, int imageWidth, 207b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk int imageHeight, int viewWidth, int viewHeight) { 208ec1f915006e5ec2db8be633b5d3d73e568951da4John Hoford tmp.set(0, 0, imageHeight, imageWidth); 209ec1f915006e5ec2db8be633b5d3d73e568951da4John Hoford m.mapRect(tmp); 210ec1f915006e5ec2db8be633b5d3d73e568951da4John Hoford float top = tmp.top; 211ec1f915006e5ec2db8be633b5d3d73e568951da4John Hoford float bottom = tmp.bottom; 212ec1f915006e5ec2db8be633b5d3d73e568951da4John Hoford float left = tmp.left; 213ec1f915006e5ec2db8be633b5d3d73e568951da4John Hoford float right = tmp.right; 214ec1f915006e5ec2db8be633b5d3d73e568951da4John Hoford m.mapRect(tmp); 215ec1f915006e5ec2db8be633b5d3d73e568951da4John Hoford int iw,ih; 216b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk if (GeometryMathUtils.needsDimensionSwap(h.rotation)) { 217b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk tmp.set(0, 0, imageHeight, imageWidth); 218ec1f915006e5ec2db8be633b5d3d73e568951da4John Hoford iw = imageHeight; 219ec1f915006e5ec2db8be633b5d3d73e568951da4John Hoford ih = imageWidth; 220b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk } else { 221b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk tmp.set(0, 0, imageWidth, imageHeight); 222ec1f915006e5ec2db8be633b5d3d73e568951da4John Hoford iw = imageWidth; 223ec1f915006e5ec2db8be633b5d3d73e568951da4John Hoford ih = imageHeight; 224b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk } 225ec1f915006e5ec2db8be633b5d3d73e568951da4John Hoford float scale = GeometryMathUtils.scale(iw, ih, viewWidth, viewHeight); 226ec1f915006e5ec2db8be633b5d3d73e568951da4John Hoford scale *= GeometryMathUtils.SHOW_SCALE; 227b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk GeometryMathUtils.scaleRect(tmp, scale); 228b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk getUntranslatedStraightenCropBounds(tmp, mAngle); 229b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk tmp.offset(viewWidth / 2f - tmp.centerX(), viewHeight / 2f - tmp.centerY()); 230b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk h.straighten = 0; 231b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk Matrix m1 = GeometryMathUtils.getFullGeometryToScreenMatrix(h, imageWidth, 232b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk imageHeight, viewWidth, viewHeight); 233b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk m.reset(); 234b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk m1.invert(m); 235b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mCrop.set(tmp); 236b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk m.mapRect(mCrop); 237b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk FilterCropRepresentation.findNormalizedCrop(mCrop, imageWidth, imageHeight); 23862e962bcb9fc03f3cfeac5ece8d3e95fc2dd0718Ruben Brunk } 23962e962bcb9fc03f3cfeac5ece8d3e95fc2dd0718Ruben Brunk 24062e962bcb9fc03f3cfeac5ece8d3e95fc2dd0718Ruben Brunk 24162e962bcb9fc03f3cfeac5ece8d3e95fc2dd0718Ruben Brunk @Override 242b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk public void onDraw(Canvas canvas) { 243b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk MasterImage master = MasterImage.getImage(); 244b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk Bitmap image = master.getFiltersOnlyImage(); 245b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk if (image == null) { 24680b216d5c8e17e0358cf1508a1e177ccada8383fnicolasroard MasterImage.getImage().invalidateFiltersOnly(); 247b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk return; 248b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk } 249b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk GeometryMathUtils.initializeHolder(mDrawHolder, mLocalRep); 250b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mDrawHolder.straighten = mAngle; 251b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk int imageWidth = image.getWidth(); 252b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk int imageHeight = image.getHeight(); 253b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk int viewWidth = canvas.getWidth(); 254b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk int viewHeight = canvas.getHeight(); 2550d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard 256b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk // Get matrix for drawing bitmap 257b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk Matrix m = GeometryMathUtils.getFullGeometryToScreenMatrix(mDrawHolder, imageWidth, 258b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk imageHeight, viewWidth, viewHeight); 259b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mPaint.reset(); 260b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mPaint.setAntiAlias(true); 261b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mPaint.setFilterBitmap(true); 262b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk canvas.drawBitmap(image, m, mPaint); 2630d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard 264b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mPaint.setFilterBitmap(false); 265b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mPaint.setColor(Color.WHITE); 266b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mPaint.setStrokeWidth(2); 267b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mPaint.setStyle(Paint.Style.FILL_AND_STROKE); 268b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk updateCurrentCrop(m, mDrawHolder, mDrawRect, imageWidth, 269b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk imageHeight, viewWidth, viewHeight); 270b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk if (mFirstDrawSinceUp) { 271b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mPriorCropAtUp.set(mCrop); 272b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mLocalRep.setStraighten(mAngle); 273b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mFirstDrawSinceUp = false; 274b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk } 275805a7fe57da2534462f4720abc7fe9cdb8f7ecc9John Hoford CropDrawingUtils.drawShade(canvas, mDrawRect); 276e533f65961ed601ded1803caeab6cef0a778d2f2nicolasroard // Draw the grid 2777a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard if (mState == MODES.MOVE || mGridAlpha > 0) { 2780d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard canvas.save(); 279b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk canvas.clipRect(mDrawRect); 280805a7fe57da2534462f4720abc7fe9cdb8f7ecc9John Hoford 2817a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard float step = Math.max(viewWidth, viewHeight) / NBLINES; 2820d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard float p = 0; 283805a7fe57da2534462f4720abc7fe9cdb8f7ecc9John Hoford for (int i = 1; i < NBLINES; i++) { 2840d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard p = i * step; 2857a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard int alpha = (int) (mDefaultGridAlpha * mGridAlpha); 2867a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard if (alpha == 0 && mState == MODES.MOVE) { 2877a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard alpha = mDefaultGridAlpha; 2887a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard } 2897a53c3d54ed06cc2fe0440fcaa01fa879d19dc88nicolasroard mPaint.setAlpha(alpha); 290b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk canvas.drawLine(p, 0, p, viewHeight, mPaint); 291998defa31aeb510a1c3c784719100f9cfbf50474John Hoford canvas.drawLine(0, p, viewWidth, p, mPaint); 2920d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard } 2930d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard canvas.restore(); 2940d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard } 295b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mPaint.reset(); 296b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mPaint.setColor(Color.WHITE); 297b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mPaint.setStyle(Style.STROKE); 298b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mPaint.setStrokeWidth(3); 299b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mDrawPath.reset(); 300805a7fe57da2534462f4720abc7fe9cdb8f7ecc9John Hoford 301805a7fe57da2534462f4720abc7fe9cdb8f7ecc9John Hoford 302b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk mDrawPath.addRect(mDrawRect, Path.Direction.CW); 303b0f7a8f7f7d95ae12e92f529fd9a8a37f75b105cRuben Brunk canvas.drawPath(mDrawPath, mPaint); 3040d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard } 3050d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard 306d61a2f9fcaad0309132b6b9b666c3dc6df62fed7John Hoford public void setEditor(EditorStraighten editorStraighten) { 307d61a2f9fcaad0309132b6b9b666c3dc6df62fed7John Hoford mEditorStraighten = editorStraighten; 308d61a2f9fcaad0309132b6b9b666c3dc6df62fed7John Hoford } 309d61a2f9fcaad0309132b6b9b666c3dc6df62fed7John Hoford 3100d7cdf8e763fb65c32bfad65245b3753deb75737nicolasroard} 311