summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRuben Brunk <rubenbrunk@google.com>2012-10-12 05:52:06 -0700
committerRuben Brunk <rubenbrunk@google.com>2012-10-12 13:02:45 -0700
commit99abd47222e829493b0757fe332bb83926c5d85d (patch)
tree2a629cef3abe01e322385377170bc24f3479ac1b
parent98de2e2ff9ab7959ee7d6035a9f87ed39ebc7537 (diff)
downloadandroid_packages_apps_Snap-99abd47222e829493b0757fe332bb83926c5d85d.tar.gz
android_packages_apps_Snap-99abd47222e829493b0757fe332bb83926c5d85d.tar.bz2
android_packages_apps_Snap-99abd47222e829493b0757fe332bb83926c5d85d.zip
Adding crop UI. Fixes a number of other UI bugs.
Bug:7337191 Change-Id: If63dbdac6722ad4fc6c30c165d6c2eeb7011c240
-rw-r--r--src/com/android/gallery3d/filtershow/FilterShowActivity.java19
-rw-r--r--src/com/android/gallery3d/filtershow/PanelController.java5
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java29
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java31
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageCrop.java330
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java289
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java21
7 files changed, 417 insertions, 307 deletions
diff --git a/src/com/android/gallery3d/filtershow/FilterShowActivity.java b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
index e8770548d..d3080593f 100644
--- a/src/com/android/gallery3d/filtershow/FilterShowActivity.java
+++ b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
@@ -77,7 +77,7 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
private ImageBorder mImageBorders = null;
private ImageStraighten mImageStraighten = null;
private ImageZoom mImageZoom = null;
- private final ImageCrop mImageCrop = null;
+ private ImageCrop mImageCrop = null;
private ImageRotate mImageRotate = null;
private ImageFlip mImageFlip = null;
@@ -140,8 +140,7 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
mImageBorders = (ImageBorder) findViewById(R.id.imageBorder);
mImageStraighten = (ImageStraighten) findViewById(R.id.imageStraighten);
mImageZoom = (ImageZoom) findViewById(R.id.imageZoom);
- // TODO: implement crop
- // mImageCrop = (ImageCrop) findViewById(R.id.imageCrop);
+ mImageCrop = (ImageCrop) findViewById(R.id.imageCrop);
mImageRotate = (ImageRotate) findViewById(R.id.imageRotate);
mImageFlip = (ImageFlip) findViewById(R.id.imageFlip);
@@ -150,8 +149,7 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
mImageViews.add(mImageBorders);
mImageViews.add(mImageStraighten);
mImageViews.add(mImageZoom);
- // TODO: implement crop
- // mImageViews.add(mImageCrop);
+ mImageViews.add(mImageCrop);
mImageViews.add(mImageRotate);
mImageViews.add(mImageFlip);
@@ -180,9 +178,8 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
mImageStraighten.setMaster(mImageShow);
mImageZoom.setImageLoader(mImageLoader);
mImageZoom.setMaster(mImageShow);
- // TODO: implement crop
- // mImageCrop.setImageLoader(mImageLoader);
- // mImageCrop.setMaster(mImageShow);
+ mImageCrop.setImageLoader(mImageLoader);
+ mImageCrop.setMaster(mImageShow);
mImageRotate.setImageLoader(mImageLoader);
mImageRotate.setMaster(mImageShow);
mImageFlip.setImageLoader(mImageLoader);
@@ -192,8 +189,7 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
mPanelController.addImageView(findViewById(R.id.imageCurves));
mPanelController.addImageView(findViewById(R.id.imageBorder));
mPanelController.addImageView(findViewById(R.id.imageStraighten));
- // TODO: implement crop
- // mPanelController.addImageView(findViewById(R.id.imageCrop));
+ mPanelController.addImageView(findViewById(R.id.imageCrop));
mPanelController.addImageView(findViewById(R.id.imageRotate));
mPanelController.addImageView(findViewById(R.id.imageFlip));
mPanelController.addImageView(findViewById(R.id.imageZoom));
@@ -203,8 +199,7 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
mPanelController.addPanel(mGeometryButton, mListGeometry, 2);
mPanelController.addComponent(mGeometryButton, findViewById(R.id.straightenButton));
- // TODO: implement crop
-// mPanelController.addComponent(mGeometryButton, findViewById(R.id.cropButton));
+ mPanelController.addComponent(mGeometryButton, findViewById(R.id.cropButton));
mPanelController.addComponent(mGeometryButton, findViewById(R.id.rotateButton));
mPanelController.addComponent(mGeometryButton, findViewById(R.id.flipButton));
diff --git a/src/com/android/gallery3d/filtershow/PanelController.java b/src/com/android/gallery3d/filtershow/PanelController.java
index a937452b3..963d17a6f 100644
--- a/src/com/android/gallery3d/filtershow/PanelController.java
+++ b/src/com/android/gallery3d/filtershow/PanelController.java
@@ -400,16 +400,13 @@ public class PanelController implements OnClickListener {
mUtilityPanel.setEffectName(ename);
break;
}
- /*
- // TODO: implement crop
case R.id.cropButton: {
mCurrentImage = showImageView(R.id.imageCrop);
String ename = mCurrentImage.getContext().getString(R.string.crop);
mUtilityPanel.setEffectName(ename);
- mUtilityPanel.showParameter(false);
+ mUtilityPanel.setShowParameter(false);
break;
}
- */
case R.id.rotateButton: {
mCurrentImage = showImageView(R.id.imageRotate);
String ename = mCurrentImage.getContext().getString(R.string.rotate);
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java
index 527800e13..9bdffee2e 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java
@@ -20,6 +20,8 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.RectF;
import com.android.gallery3d.filtershow.imageshow.GeometryMetadata;
@@ -61,15 +63,18 @@ public class ImageFilterGeometry extends ImageFilter {
native protected void nativeApplyFilterStraighten(Bitmap src, int srcWidth, int srcHeight,
Bitmap dst, int dstWidth, int dstHeight, float straightenAngle);
- public Matrix buildMatrix(Bitmap bitmap, boolean rotated) {
- float dx = bitmap.getWidth()/2;
- float dy = bitmap.getHeight()/2;
+ public Matrix buildMatrix(RectF r) {
+ float dx = r.width()/2;
+ float dy = r.height()/2;
if(mGeometry.hasSwitchedWidthHeight()){
float temp = dx;
dx = dy;
dy = temp;
}
- Matrix m = mGeometry.buildGeometryMatrix(bitmap.getWidth(), bitmap.getHeight(), 1f/mGeometry.getScaleFactor(), dx, dy);
+ float w = r.left * 2 + r.width();
+ float h = r.top * 2 + r.height();
+ Matrix m = mGeometry.buildGeometryMatrix(w, h, 1f, dx, dy, false);
+
return m;
}
@@ -78,18 +83,18 @@ public class ImageFilterGeometry extends ImageFilter {
// TODO: implement bilinear or bicubic here... for now, just use
// canvas to do a simple implementation...
// TODO: and be more memory efficient! (do it in native?)
-
+ Rect cropBounds = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
+ RectF c = mGeometry.getCropBounds();
+ if(c != null && c.width() > 0 && c.height() > 0)
+ c.roundOut(cropBounds);
Bitmap temp = null;
- float rotation = mGeometry.getRotation();
- boolean rotated = false;
- if (rotation == 0 || rotation % 180 == 0) {
- temp = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), mConfig);
+ if (mGeometry.hasSwitchedWidthHeight()) {
+ temp = Bitmap.createBitmap(cropBounds.height(), cropBounds.width(), mConfig);
} else {
- temp = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getWidth(), mConfig);
- rotated = true;
+ temp = Bitmap.createBitmap(cropBounds.width(), cropBounds.height(), mConfig);
}
- Matrix drawMatrix = buildMatrix(bitmap, rotated);
+ Matrix drawMatrix = buildMatrix(c);
Canvas canvas = new Canvas(temp);
canvas.drawBitmap(bitmap, drawMatrix, new Paint());
return temp;
diff --git a/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java b/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java
index a14e065b2..d412f5890 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java
@@ -33,7 +33,6 @@ public class GeometryMetadata {
private final RectF mPhotoBounds = new RectF();
private FLIP mFlip = FLIP.NONE;
-
private RectF mBounds = new RectF();
public enum FLIP {
@@ -47,7 +46,7 @@ public class GeometryMetadata {
set(g);
}
- public Bitmap apply(Bitmap original, float scaleFactor, boolean highQuality){
+ public Bitmap apply(Bitmap original, float scaleFactor, boolean highQuality) {
mImageFilter.setGeometryMetadata(this);
Bitmap m = mImageFilter.apply(original, scaleFactor, highQuality);
return m;
@@ -87,7 +86,6 @@ public class GeometryMetadata {
return new RectF(mPhotoBounds);
}
-
public void setScaleFactor(float scale) {
mScaleFactor = scale;
}
@@ -182,27 +180,34 @@ public class GeometryMetadata {
}
}
- public boolean hasSwitchedWidthHeight(){
+ 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;
+ public Matrix buildGeometryMatrix(float width, float height, float scaling, float dx, float dy,
+ float rotation) {
+ 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.postRotate(rotation);
m.postScale(scaling, scaling);
m.postTranslate(dx, dy);
return m;
}
- public Matrix buildGeometryUIMatrix(float scaling, float dx, float dy){
+ public Matrix buildGeometryMatrix(float width, float height, float scaling, float dx, float dy,
+ boolean onlyRotate) {
+ float rot = mRotation;
+ if (!onlyRotate) {
+ rot += mStraightenRotation;
+ }
+ return buildGeometryMatrix(width, height, scaling, dx, dy, rot);
+ }
+
+ public Matrix buildGeometryUIMatrix(float scaling, float dx, float dy) {
float w = mPhotoBounds.width();
float h = mPhotoBounds.height();
- return buildGeometryMatrix(w, h, scaling, dx, dy);
+ return buildGeometryMatrix(w, h, scaling, dx, dy, false);
}
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageCrop.java b/src/com/android/gallery3d/filtershow/imageshow/ImageCrop.java
index 90d36e942..4d171bf4c 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageCrop.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageCrop.java
@@ -22,12 +22,10 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
-import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
-
import com.android.gallery3d.R;
public class ImageCrop extends ImageGeometry {
@@ -40,19 +38,14 @@ public class ImageCrop extends ImageGeometry {
private static final float MIN_CROP_WIDTH_HEIGHT = 0.1f;
private static final int TOUCH_TOLERANCE = 30;
- private static final int SHADOW_ALPHA = 160;
- private final float mAspectWidth = 4;
- private final float mAspectHeight = 3;
- private final boolean mFixAspectRatio = false; // not working yet
+ private boolean mFirstDraw = true;
+ private float mAspectWidth = 1;
+ private float mAspectHeight = 1;
+ private boolean mFixAspectRatio = false;
private final Paint borderPaint;
- private float mCropOffsetX = 0;
- private float mCropOffsetY = 0;
- private float mPrevOffsetX = 0;
- private float mPrevOffsetY = 0;
-
private int movingEdges;
private final Drawable cropIndicator;
private final int indicatorSize;
@@ -86,22 +79,21 @@ public class ImageCrop extends ImageGeometry {
}
private float getScaledMinWidthHeight() {
- RectF disp = getLocalDisplayBounds();
+ RectF disp = new RectF(0, 0, getWidth(), getHeight());
float scaled = Math.min(disp.width(), disp.height()) * MIN_CROP_WIDTH_HEIGHT
- / getLocalScale();
+ / computeScale(getWidth(), getHeight());
return scaled;
}
- protected static Matrix getCropRotationMatrix(float rotation, RectF localImage) {
- Matrix m = new Matrix();
- m.setRotate(rotation, localImage.centerX(), localImage.centerY());
+ protected Matrix getCropRotationMatrix(float rotation, RectF localImage) {
+ Matrix m = getLocalGeoFlipMatrix(localImage.width(), localImage.height());
+ m.postRotate(rotation, localImage.centerX(), localImage.centerY());
if (!m.rectStaysRect()) {
return null;
}
return m;
}
- @Override
protected RectF getCropBoundsDisplayed() {
RectF bounds = getLocalCropBounds();
RectF crop = new RectF(bounds);
@@ -115,7 +107,7 @@ public class ImageCrop extends ImageGeometry {
m.mapRect(crop);
}
m = new Matrix();
- float zoom = getLocalScale();
+ float zoom = computeScale(getWidth(), getHeight());
m.setScale(zoom, zoom, mCenterX, mCenterY);
m.preTranslate(mXOffset, mYOffset);
m.mapRect(crop);
@@ -137,6 +129,44 @@ public class ImageCrop extends ImageGeometry {
return crop;
}
+ private RectF getUnrotatedCropBounds(RectF cropBounds) {
+ Matrix m = getCropRotationMatrix(getLocalRotation(), getLocalPhotoBounds());
+
+ if (m == null) {
+ if (LOGV)
+ Log.v(LOGTAG, "FAILED TO GET ROTATION MATRIX");
+ return null;
+ }
+ Matrix m0 = new Matrix();
+ if (!m.invert(m0)) {
+ if (LOGV)
+ Log.v(LOGTAG, "FAILED TO INVERT ROTATION MATRIX");
+ return null;
+ }
+ RectF crop = new RectF(cropBounds);
+ if (!m0.mapRect(crop)) {
+ if (LOGV)
+ Log.v(LOGTAG, "FAILED TO UNROTATE CROPPING BOUNDS");
+ return null;
+ }
+ return crop;
+ }
+
+ private RectF getRotatedStraightenBounds() {
+ RectF straightenBounds = getUntranslatedStraightenCropBounds(getLocalPhotoBounds(),
+ getLocalStraighten());
+ Matrix m = getCropRotationMatrix(getLocalRotation(), getLocalPhotoBounds());
+
+ if (m == null) {
+ if (LOGV)
+ Log.v(LOGTAG, "FAILED TO MAP STRAIGHTEN BOUNDS TO RECTANGLE");
+ return null;
+ } else {
+ m.mapRect(straightenBounds);
+ }
+ return straightenBounds;
+ }
+
/**
* Sets cropped bounds; modifies the bounds if it's smaller than the allowed
* dimensions.
@@ -145,16 +175,33 @@ public class ImageCrop extends ImageGeometry {
// Avoid cropping smaller than minimum width or height.
RectF cbounds = new RectF(bounds);
float minWidthHeight = getScaledMinWidthHeight();
+ float aw = mAspectWidth;
+ float ah = mAspectHeight;
+ if (mFixAspectRatio) {
+ minWidthHeight /= aw * ah;
+ int r = (int) (getLocalRotation() / 90);
+ if (r % 2 != 0) {
+ float temp = aw;
+ aw = ah;
+ ah = temp;
+ }
+ }
float newWidth = cbounds.width();
float newHeight = cbounds.height();
- if (newWidth < minWidthHeight) {
- newWidth = minWidthHeight;
- }
- if (newHeight < minWidthHeight) {
- newHeight = minWidthHeight;
+ if (mFixAspectRatio) {
+ if (newWidth < (minWidthHeight * aw) || newHeight < (minWidthHeight * ah)) {
+ newWidth = minWidthHeight * aw;
+ newHeight = minWidthHeight * ah;
+ }
+ } else {
+ if (newWidth < minWidthHeight) {
+ newWidth = minWidthHeight;
+ }
+ if (newHeight < minWidthHeight) {
+ newHeight = minWidthHeight;
+ }
}
-
RectF pbounds = getLocalPhotoBounds();
if (pbounds.width() < minWidthHeight) {
newWidth = pbounds.width();
@@ -164,18 +211,14 @@ public class ImageCrop extends ImageGeometry {
}
cbounds.set(cbounds.left, cbounds.top, cbounds.left + newWidth, cbounds.top + newHeight);
- RectF snappedCrop = findCropBoundForRotatedImg(cbounds, pbounds, getLocalStraighten(),
- mCenterX - mXOffset, mCenterY - mYOffset);
-
- RectF straightenBounds = getUntranslatedStraightenCropBounds(getLocalPhotoBounds(), getLocalStraighten());
- snappedCrop.intersect(straightenBounds);
-
+ RectF straightenBounds = getUntranslatedStraightenCropBounds(getLocalPhotoBounds(),
+ getLocalStraighten());
+ cbounds.intersect(straightenBounds);
if (mFixAspectRatio) {
- // TODO: add aspect ratio stuff
- fixAspectRatio(snappedCrop, mAspectWidth, mAspectHeight);
+ fixAspectRatio(cbounds, aw, ah);
}
- setLocalCropBounds(snappedCrop);
+ setLocalCropBounds(cbounds);
invalidate();
}
@@ -202,33 +245,88 @@ public class ImageCrop extends ImageGeometry {
else if (bottom <= TOUCH_TOLERANCE) {
movingEdges |= MOVE_BOTTOM;
}
+ // Check inside block.
+ if (cropped.contains(x, y) && (movingEdges == 0)) {
+ movingEdges = MOVE_BLOCK;
+ }
invalidate();
}
private void moveEdges(float dX, float dY) {
RectF cropped = getRotatedCropBounds();
float minWidthHeight = getScaledMinWidthHeight();
- float scale = getLocalScale();
+ float scale = computeScale(getWidth(), getHeight());
float deltaX = dX / scale;
float deltaY = dY / scale;
- if (movingEdges == MOVE_BLOCK) {
- // TODO
+ int select = movingEdges;
+ if (mFixAspectRatio && (select != MOVE_BLOCK)) {
+ if ((select & MOVE_LEFT) != 0) {
+ select &= ~MOVE_BOTTOM;
+ select |= MOVE_TOP;
+ deltaY = getNewHeightForWidthAspect(deltaX, mAspectWidth, mAspectHeight);
+ }
+ if ((select & MOVE_TOP) != 0) {
+ select &= ~MOVE_RIGHT;
+ select |= MOVE_LEFT;
+ deltaX = getNewWidthForHeightAspect(deltaY, mAspectWidth, mAspectHeight);
+ }
+ if ((select & MOVE_RIGHT) != 0) {
+ select &= ~MOVE_TOP;
+ select |= MOVE_BOTTOM;
+ deltaY = getNewHeightForWidthAspect(deltaX, mAspectWidth, mAspectHeight);
+ }
+ if ((select & MOVE_BOTTOM) != 0) {
+ select &= ~MOVE_LEFT;
+ select |= MOVE_RIGHT;
+ deltaX = getNewWidthForHeightAspect(deltaY, mAspectWidth, mAspectHeight);
+ }
+ }
+
+ if (select == MOVE_BLOCK) {
+ RectF straight = getRotatedStraightenBounds();
+ // Move the whole cropped bounds within the photo display bounds.
+ deltaX = (deltaX > 0) ? Math.min(straight.right - cropped.right, deltaX)
+ : Math.max(straight.left - cropped.left, deltaX);
+ deltaY = (deltaY > 0) ? Math.min(straight.bottom - cropped.bottom, deltaY)
+ : Math.max(straight.top - cropped.top, deltaY);
+ cropped.offset(deltaX, deltaY);
} else {
- if ((movingEdges & MOVE_LEFT) != 0) {
- cropped.left = Math.min(cropped.left + deltaX, cropped.right - minWidthHeight);
- fixRectAspectW(cropped);
+ float dx = 0;
+ float dy = 0;
+ if ((select & MOVE_LEFT) != 0) {
+ dx = Math.min(cropped.left + deltaX, cropped.right - minWidthHeight) - cropped.left;
+ }
+ if ((select & MOVE_TOP) != 0) {
+ dy = Math.min(cropped.top + deltaY, cropped.bottom - minWidthHeight) - cropped.top;
+ }
+ if ((select & MOVE_RIGHT) != 0) {
+ dx = Math.max(cropped.right + deltaX, cropped.left + minWidthHeight)
+ - cropped.right;
}
- if ((movingEdges & MOVE_TOP) != 0) {
- cropped.top = Math.min(cropped.top + deltaY, cropped.bottom - minWidthHeight);
- fixRectAspectH(cropped);
+ if ((select & MOVE_BOTTOM) != 0) {
+ dy = Math.max(cropped.bottom + deltaY, cropped.top + minWidthHeight)
+ - cropped.bottom;
}
- if ((movingEdges & MOVE_RIGHT) != 0) {
- cropped.right = Math.max(cropped.right + deltaX, cropped.left + minWidthHeight);
- fixRectAspectW(cropped);
+
+ if (mFixAspectRatio) {
+ if (dx < dy) {
+ dy = getNewHeightForWidthAspect(dx, mAspectWidth, mAspectHeight);
+ } else {
+ dx = getNewWidthForHeightAspect(dy, mAspectWidth, mAspectHeight);
+ }
+ }
+
+ if ((select & MOVE_LEFT) != 0) {
+ cropped.left += dx;
}
- if ((movingEdges & MOVE_BOTTOM) != 0) {
- cropped.bottom = Math.max(cropped.bottom + deltaY, cropped.top + minWidthHeight);
- fixRectAspectH(cropped);
+ if ((select & MOVE_TOP) != 0) {
+ cropped.top += dy;
+ }
+ if ((select & MOVE_RIGHT) != 0) {
+ cropped.right += dx;
+ }
+ if ((select & MOVE_BOTTOM) != 0) {
+ cropped.bottom += dy;
}
}
Matrix m = getCropRotationMatrix(getLocalRotation(), getLocalPhotoBounds());
@@ -244,24 +342,6 @@ public class ImageCrop extends ImageGeometry {
setCropBounds(cropped);
}
- private void fixRectAspectH(RectF cropped) {
- if (mFixAspectRatio) {
- float half = getNewWidthForHeightAspect(cropped.height(), mAspectWidth, mAspectHeight) / 2;
- float mid = (cropped.right - cropped.left) / 2;
- cropped.left = mid - half;
- cropped.right = mid + half;
- }
- }
-
- private void fixRectAspectW(RectF cropped) {
- if (mFixAspectRatio) {
- float half = getNewHeightForWidthAspect(cropped.width(), mAspectWidth, mAspectHeight) / 2;
- float mid = (cropped.bottom - cropped.top) / 2;
- cropped.top = mid - half;
- cropped.bottom = mid + half;
- }
- }
-
private void drawIndicator(Canvas canvas, Drawable indicator, float centerX, float centerY) {
int left = (int) centerX - indicatorSize / 2;
int top = (int) centerY - indicatorSize / 2;
@@ -273,81 +353,111 @@ public class ImageCrop extends ImageGeometry {
protected void setActionDown(float x, float y) {
super.setActionDown(x, y);
detectMovingEdges(x, y);
- if (movingEdges == 0) {
- mPrevOffsetX = mCropOffsetX;
- mPrevOffsetY = mCropOffsetY;
- }
+ }
+
+ @Override
+ protected void setActionUp() {
+ super.setActionUp();
+ movingEdges = 0;
}
@Override
protected void setActionMove(float x, float y) {
- if (movingEdges != 0) {
+ if (movingEdges != 0)
moveEdges(x - mCurrentX, y - mCurrentY);
+
+ super.setActionMove(x, y);
+ }
+
+ private void cropSetup() {
+ if (mFixAspectRatio) {
+ RectF cb = getRotatedCropBounds();
+ fixAspectRatio(cb, mAspectWidth, mAspectHeight);
+ RectF cb0 = getUnrotatedCropBounds(cb);
+ setCropBounds(cb0);
} else {
- float dx = x - mTouchCenterX;
- float dy = y - mTouchCenterY;
- mCropOffsetX = dx + mPrevOffsetX;
- mCropOffsetY = dy + mPrevOffsetY;
+ setCropBounds(getLocalCropBounds());
}
- super.setActionMove(x, y);
}
@Override
protected void gainedVisibility() {
- setCropBounds(getLocalCropBounds());
- super.gainedVisibility();
+ cropSetup();
+ mFirstDraw = true;
}
- protected RectF drawCrop(Canvas canvas, Paint p, RectF cropBounds, float scale,
- float rotation, float centerX, float centerY, float offsetX, float offsetY) {
- RectF crop = new RectF(cropBounds);
- Matrix m = new Matrix();
- m.preTranslate(offsetX, offsetY);
- m.mapRect(crop);
+ @Override
+ public void resetParameter() {
+ super.resetParameter();
+ cropSetup();
+ }
- m.setRotate(rotation, centerX, centerY);
- if (!m.rectStaysRect()) {
- float[] corners = getCornersFromRect(crop);
- m.mapPoints(corners);
- drawClosedPath(canvas, p, corners);
- } else {
- RectF crop2 = new RectF(crop);
- m.mapRect(crop2);
- Path path = new Path();
- path.addRect(crop2, Path.Direction.CCW);
- canvas.drawPath(path, p);
- }
- return crop;
+ @Override
+ protected void lostVisibility() {
}
@Override
protected void drawShape(Canvas canvas, Bitmap image) {
+ // TODO: move style to xml
gPaint.setAntiAlias(true);
gPaint.setFilterBitmap(true);
gPaint.setDither(true);
gPaint.setARGB(255, 255, 255, 255);
- drawTransformedBitmap(canvas, image, gPaint, false);
- float scale = getLocalScale();
+ if (mFirstDraw) {
+ cropSetup();
+ mFirstDraw = false;
+ }
float rotation = getLocalRotation();
-
- RectF scaledCrop = drawCrop(canvas, gPaint, getLocalCropBounds(), scale,
- rotation, mCenterX, mCenterY, mXOffset,
- mYOffset);
-
- boolean notMoving = movingEdges == 0;
- if (((movingEdges & MOVE_TOP) != 0) || notMoving) {
+ drawTransformedBitmap(canvas, image, gPaint, true);
+
+ gPaint.setARGB(255, 125, 255, 128);
+ gPaint.setStrokeWidth(3);
+ gPaint.setStyle(Paint.Style.STROKE);
+ drawStraighten(canvas, gPaint);
+ RectF scaledCrop = unrotatedCropBounds();
+ int decoded_moving = decoder(movingEdges, rotation);
+ canvas.save();
+ canvas.rotate(rotation, mCenterX, mCenterY);
+ boolean notMoving = decoded_moving == 0;
+ if (((decoded_moving & MOVE_TOP) != 0) || notMoving) {
drawIndicator(canvas, cropIndicator, scaledCrop.centerX(), scaledCrop.top);
}
- if (((movingEdges & MOVE_BOTTOM) != 0) || notMoving) {
+ if (((decoded_moving & MOVE_BOTTOM) != 0) || notMoving) {
drawIndicator(canvas, cropIndicator, scaledCrop.centerX(), scaledCrop.bottom);
}
- if (((movingEdges & MOVE_LEFT) != 0) || notMoving) {
+ if (((decoded_moving & MOVE_LEFT) != 0) || notMoving) {
drawIndicator(canvas, cropIndicator, scaledCrop.left, scaledCrop.centerY());
}
- if (((movingEdges & MOVE_RIGHT) != 0) || notMoving) {
+ if (((decoded_moving & MOVE_RIGHT) != 0) || notMoving) {
drawIndicator(canvas, cropIndicator, scaledCrop.right, scaledCrop.centerY());
}
+ canvas.restore();
+ }
+
+ private int bitCycleLeft(int x, int times, int d){
+ int mask = (1 << d) - 1;
+ int mout = x & mask;
+ times %= d;
+ int hi = mout >> (d - times);
+ int low = (mout << times) & mask;
+ int ret = x & ~mask;
+ ret |= low;
+ ret |= hi;
+ return ret;
}
-}
+ protected int decoder(int movingEdges, float rotation) {
+ int rot = constrainedRotation(rotation);
+ switch(rot){
+ case 90:
+ return bitCycleLeft(movingEdges, 3, 4);
+ case 180:
+ return bitCycleLeft(movingEdges, 2, 4);
+ case 270:
+ return bitCycleLeft(movingEdges, 1, 4);
+ default:
+ return movingEdges;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java b/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java
index 8da673ba6..d8d03dc22 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java
@@ -26,7 +26,6 @@ import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
@@ -49,7 +48,7 @@ public abstract class ImageGeometry extends ImageSlave {
protected float mTouchCenterY;
// Local geometry data
- private GeometryMetadata mLocalGeoMetadata = null;
+ private GeometryMetadata mLocalGeometry = null;
private RectF mLocalDisplayBounds = null;
protected float mXOffset = 0;
protected float mYOffset = 0;
@@ -75,9 +74,9 @@ public abstract class ImageGeometry extends ImageSlave {
calculateLocalScalingFactorAndOffset();
}
- private float computeScale(float width, float height) {
- float imageWidth = mLocalGeoMetadata.getPhotoBounds().width();
- float imageHeight = mLocalGeoMetadata.getPhotoBounds().height();
+ protected float computeScale(float width, float height) {
+ float imageWidth = mLocalGeometry.getPhotoBounds().width();
+ float imageHeight = mLocalGeometry.getPhotoBounds().height();
float zoom = width / imageWidth;
if (imageHeight > imageWidth) {
zoom = height / imageHeight;
@@ -86,9 +85,9 @@ public abstract class ImageGeometry extends ImageSlave {
}
private void calculateLocalScalingFactorAndOffset() {
- if (mLocalGeoMetadata == null || mLocalDisplayBounds == null)
+ if (mLocalGeometry == null || mLocalDisplayBounds == null)
return;
- RectF imageBounds = mLocalGeoMetadata.getPhotoBounds();
+ RectF imageBounds = mLocalGeometry.getPhotoBounds();
float imageWidth = imageBounds.width();
float imageHeight = imageBounds.height();
float displayWidth = mLocalDisplayBounds.width();
@@ -98,6 +97,7 @@ public abstract class ImageGeometry extends ImageSlave {
mCenterY = displayHeight / 2;
mYOffset = (displayHeight - imageHeight) / 2.0f;
mXOffset = (displayWidth - imageWidth) / 2.0f;
+ updateScale();
}
@Override
@@ -113,16 +113,16 @@ public abstract class ImageGeometry extends ImageSlave {
// Overwrites local with master
protected void syncLocalToMasterGeometry() {
- mLocalGeoMetadata = getMaster().getGeometry();
+ mLocalGeometry = getMaster().getGeometry();
calculateLocalScalingFactorAndOffset();
}
protected RectF getLocalPhotoBounds() {
- return mLocalGeoMetadata.getPhotoBounds();
+ return mLocalGeometry.getPhotoBounds();
}
protected RectF getLocalCropBounds() {
- return mLocalGeoMetadata.getCropBounds();
+ return mLocalGeometry.getCropBounds();
}
protected RectF getLocalDisplayBounds() {
@@ -130,52 +130,62 @@ public abstract class ImageGeometry extends ImageSlave {
}
protected float getLocalScale() {
- return mLocalGeoMetadata.getScaleFactor();
+ return mLocalGeometry.getScaleFactor();
}
protected float getLocalRotation() {
- return mLocalGeoMetadata.getRotation();
+ return mLocalGeometry.getRotation();
}
protected float getLocalStraighten() {
- return mLocalGeoMetadata.getStraightenRotation();
+ return mLocalGeometry.getStraightenRotation();
}
protected void setLocalScale(float s) {
- mLocalGeoMetadata.setScaleFactor(s);
+ mLocalGeometry.setScaleFactor(s);
}
- protected void updateScale(){
- RectF bounds = getUntranslatedStraightenCropBounds(mLocalGeoMetadata.getPhotoBounds(),
+ protected void updateScale() {
+ RectF bounds = getUntranslatedStraightenCropBounds(mLocalGeometry.getPhotoBounds(),
getLocalStraighten());
float zoom = computeScale(bounds.width(), bounds.height());
setLocalScale(zoom);
}
protected void setLocalRotation(float r) {
- mLocalGeoMetadata.setRotation(r);
+ mLocalGeometry.setRotation(r);
updateScale();
}
- private Matrix getLocalGeoMatrix(float scaling, float dx, float dy) {
- return mLocalGeoMetadata.buildGeometryUIMatrix(scaling, dx, dy);
+ /**
+ * Constrains rotation to be in [0, 90, 180, 270].
+ */
+ protected int constrainedRotation(float rotation) {
+ int r = (int) ((rotation % 360) / 90);
+ r = (r < 0) ? (r + 4) : r;
+ return r * 90;
+ }
+
+ protected Matrix getLocalGeoFlipMatrix(float width, float height) {
+ return mLocalGeometry.getFlipMatrix(width, height);
}
protected void setLocalStraighten(float r) {
- mLocalGeoMetadata.setStraightenRotation(r);
+ mLocalGeometry.setStraightenRotation(r);
updateScale();
}
protected void setLocalCropBounds(RectF c) {
- mLocalGeoMetadata.setCropBounds(c);
+ mLocalGeometry.setCropBounds(c);
+ updateScale();
}
protected FLIP getLocalFlip() {
- return mLocalGeoMetadata.getFlipType();
+ return mLocalGeometry.getFlipType();
}
protected void setLocalFlip(FLIP flip) {
- mLocalGeoMetadata.setFlipType(flip);
+ mLocalGeometry.setFlipType(flip);
}
protected float getTotalLocalRotation() {
@@ -191,35 +201,18 @@ public abstract class ImageGeometry extends ImageSlave {
protected static float[] getCornersFromRect(RectF r) {
// Order is:
// 0------->1
- // ^ |
- // | v
+ // ^ |
+ // | v
// 3<-------2
float[] corners = {
r.left, r.top, // 0
r.right, r.top, // 1
r.right, r.bottom,// 2
- r.left, r.bottom
- // 3
+ r.left, r.bottom // 3
};
return corners;
}
- // 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) {
- Matrix m = new Matrix();
- float[] cropEdges = getCornersFromRect(cropBound);
- m.setRotate(rotation, centerX, centerY);
- Matrix m0 = new Matrix();
- if (!m.invert(m0))
- return null;
- m0.mapPoints(cropEdges);
- getEdgePoints(imageBound, cropEdges);
- m.mapPoints(cropEdges);
- return trapToRect(cropEdges);
- }
-
// If edge point [x, y] in array [x0, y0, x1, y1, ...] is outside of the
// image bound rectangle, clamps it to the edge of the rectangle.
protected static void getEdgePoints(RectF imageBound, float[] array) {
@@ -231,24 +224,6 @@ public abstract class ImageGeometry extends ImageSlave {
}
}
- protected static RectF trapToRect(float[] array) {
- float dx0 = array[4] - array[0];
- float dy0 = array[5] - array[1];
- float dx1 = array[6] - array[2];
- float dy1 = array[7] - array[3];
- float l0 = dx0 * dx0 + dy0 * dy0;
- float l1 = dx1 * dx1 + dy1 * dy1;
- if (l0 > l1) {
- RectF n = new RectF(array[2], array[3], array[6], array[7]);
- n.sort();
- return n;
- } else {
- RectF n = new RectF(array[0], array[1], array[4], array[5]);
- n.sort();
- return n;
- }
- }
-
protected static Path drawClosedPath(Canvas canvas, Paint paint, float[] points) {
Path crop = new Path();
crop.moveTo(points[0], points[1]);
@@ -260,26 +235,14 @@ public abstract class ImageGeometry extends ImageSlave {
return crop;
}
- protected static float[] shortestVectorFromPointToLine(float[] point, float[] l1, float[] l2) {
- float x1 = l1[0];
- float x2 = l2[0];
- float y1 = l1[1];
- float y2 = l2[1];
- float xdelt = x2 - x1;
- float ydelt = y2 - y1;
- if (xdelt == 0 && ydelt == 0)
- return null;
- float u = ((point[0] - x1) * xdelt + (point[1] - y1) * ydelt)
- / (xdelt * xdelt + ydelt * ydelt);
- float[] ret = {
- (x1 + u * (x2 - x1)), (y1 + u * (y2 - y1))
- };
- return ret;
- }
-
protected static void fixAspectRatio(RectF r, float w, float h) {
float scale = Math.min(r.width() / w, r.height() / h);
- r.set(r.left, r.top, scale * w, scale * h);
+ float centX = r.centerX();
+ float centY = r.centerY();
+ float hw = scale * w / 2;
+ float hh = scale * h / 2;
+ r.set(centX - hw, centY - hh, centX + hw, centY + hh);
+
}
protected static float getNewHeightForWidthAspect(float width, float w, float h) {
@@ -296,6 +259,7 @@ public abstract class ImageGeometry extends ImageSlave {
if (visibility == View.VISIBLE) {
mVisibilityGained = true;
syncLocalToMasterGeometry();
+ updateScale();
gainedVisibility();
} else {
if (mVisibilityGained == true && mHasDrawn == true) {
@@ -308,7 +272,6 @@ public abstract class ImageGeometry extends ImageSlave {
protected void gainedVisibility() {
// TODO: Override this stub.
- updateScale();
}
protected void lostVisibility() {
@@ -330,7 +293,6 @@ public abstract class ImageGeometry extends ImageSlave {
case (MotionEvent.ACTION_UP):
setActionUp();
saveAndSetPreset();
- Log.v(LOGTAG, "up action");
break;
case (MotionEvent.ACTION_MOVE):
setActionMove(event.getX(), event.getY());
@@ -378,13 +340,12 @@ public abstract class ImageGeometry extends ImageSlave {
protected void saveAndSetPreset() {
ImagePreset copy = new ImagePreset(getImagePreset());
- copy.setGeometry(mLocalGeoMetadata);
+ copy.setGeometry(mLocalGeometry);
copy.setHistoryName("Geometry");
copy.setIsFx(false);
setImagePreset(copy);
}
- //
protected static float clamp(float i, float low, float high) {
return Math.max(Math.min(i, high), low);
}
@@ -413,105 +374,123 @@ public abstract class ImageGeometry extends ImageSlave {
return new RectF(left, top, right, bottom);
}
- protected static void drawShadows(Canvas canvas, Paint p, RectF innerBounds, RectF outerBounds,
- float rotation, float centerX, float centerY) {
+ protected Matrix getGeoMatrix(RectF r, boolean onlyRotate) {
+ float scale = computeScale(getWidth(), getHeight());
+ float yoff = getHeight() / 2;
+ float xoff = getWidth() / 2;
+ float w = r.left * 2 + r.width();
+ float h = r.top * 2 + r.height();
+ return mLocalGeometry.buildGeometryMatrix(w, h, scale, xoff, yoff, onlyRotate);
+ }
+
+ protected void drawImageBitmap(Canvas canvas, Bitmap bitmap, Paint paint, Matrix m) {
canvas.save();
- canvas.rotate(rotation, centerX, centerY);
- float dWidth = outerBounds.width();
- float dHeight = outerBounds.height();
- canvas.drawRect(0, 0, dWidth, innerBounds.top, p);
- canvas.drawRect(0, innerBounds.bottom, dWidth, dHeight, p);
- canvas.drawRect(0, innerBounds.top, innerBounds.left, innerBounds.bottom,
- p);
- canvas.drawRect(innerBounds.right, innerBounds.top, dWidth,
- innerBounds.bottom, p);
- canvas.rotate(-rotation, centerX, centerY);
+ canvas.drawBitmap(bitmap, m, paint);
canvas.restore();
}
- 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;
+ protected void drawImageBitmap(Canvas canvas, Bitmap bitmap, Paint paint) {
+ float scale = computeScale(getWidth(), getHeight());
+ float yoff = getHeight() / 2;
+ float xoff = getWidth() / 2;
+ Matrix m = mLocalGeometry.buildGeometryUIMatrix(scale, xoff, yoff);
+ drawImageBitmap(canvas, bitmap, paint, m);
}
- public RectF cropBounds(Bitmap bitmap) {
- Matrix boundsMatrix = computeBoundsMatrix(bitmap);
+ protected RectF straightenBounds() {
RectF bounds = getUntranslatedStraightenCropBounds(getLocalPhotoBounds(),
getLocalStraighten());
- RectF transformedBounds = new RectF(bounds);
- boundsMatrix.mapRect(transformedBounds);
- return transformedBounds;
+ Matrix m = getGeoMatrix(bounds, true);
+ m.mapRect(bounds);
+ return bounds;
}
- 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);
+ protected void drawStraighten(Canvas canvas, Paint paint) {
+ RectF bounds = straightenBounds();
canvas.save();
- canvas.drawBitmap(bitmap, m, paint);
+ canvas.drawRect(bounds, paint);
+ canvas.restore();
}
- 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();
- paint.setARGB(255, 0, 0, 0);
- drawImage(canvas, bitmap, paint);
- canvas.restore();
+ protected RectF unrotatedCropBounds() {
+ RectF bounds = getLocalCropBounds();
+ RectF pbounds = getLocalPhotoBounds();
+ float scale = computeScale(getWidth(), getHeight());
+ float yoff = getHeight() / 2;
+ float xoff = getWidth() / 2;
+ Matrix m = mLocalGeometry.buildGeometryMatrix(pbounds.width(), pbounds.height(), scale, xoff, yoff, 0);
+ m.mapRect(bounds);
+ return bounds;
+ }
+
+ protected RectF cropBounds() {
+ RectF bounds = getLocalCropBounds();
+ Matrix m = getGeoMatrix(getLocalPhotoBounds(), true);
+ m.mapRect(bounds);
+ return bounds;
+ }
+
+ // Fails for non-90 degree
+ protected void drawCrop(Canvas canvas, Paint paint) {
+ RectF bounds = cropBounds();
canvas.save();
- canvas.setMatrix(boundsMatrix);
- paint.setColor(Color.WHITE);
- paint.setStyle(Style.STROKE);
- paint.setStrokeWidth(2);
canvas.drawRect(bounds, paint);
canvas.restore();
+ }
- if (!clip) { // we display the rest of the bitmap grayed-out
- drawShadows(canvas, transformedBounds, new RectF(0, 0, w, h), paint);
+ protected void drawCropSafe(Canvas canvas, Paint paint) {
+ Matrix m = getGeoMatrix(getLocalPhotoBounds(), true);
+ RectF crop = getLocalCropBounds();
+ if (!m.rectStaysRect()) {
+ float[] corners = getCornersFromRect(crop);
+ m.mapPoints(corners);
+ drawClosedPath(canvas, paint, corners);
+ } else {
+ m.mapRect(crop);
+ Path path = new Path();
+ path.addRect(crop, Path.Direction.CCW);
+ canvas.drawPath(path, paint);
}
}
- protected RectF getCropBoundsDisplayed() {
- return getCropBoundsDisplayed(getLocalCropBounds());
+ protected void drawTransformedBitmap(Canvas canvas, Bitmap bitmap, Paint paint, boolean clip) {
+ paint.setARGB(255, 0, 0, 0);
+ drawImageBitmap(canvas, bitmap, paint);
+ paint.setColor(Color.WHITE);
+ paint.setStyle(Style.STROKE);
+ paint.setStrokeWidth(2);
+ drawCropSafe(canvas, paint);
+ paint.setARGB(128, 0, 0, 0);
+ paint.setStyle(Paint.Style.FILL);
+ drawShadows(canvas, paint, unrotatedCropBounds());
}
- protected RectF getCropBoundsDisplayed(RectF bounds) {
- RectF crop = new RectF(bounds);
- Matrix m = new Matrix();
- float zoom = getLocalScale();
- m.setScale(zoom, zoom, mCenterX, mCenterY);
- m.preTranslate(mXOffset, mYOffset);
- m.mapRect(crop);
- return crop;
+ protected void drawShadows(Canvas canvas, Paint p, RectF innerBounds) {
+ RectF display = new RectF(0, 0, getWidth(), getHeight());
+ drawShadows(canvas, p, innerBounds, display, getLocalRotation(), getWidth() / 2,
+ getHeight() / 2);
}
- protected void drawShadows(Canvas canvas, RectF innerBounds, RectF outerBounds, Paint p) {
- float dWidth = outerBounds.width();
- float dHeight = outerBounds.height();
-
- // TODO: move style to xml
- p.setARGB(128, 0, 0, 0);
- p.setStyle(Paint.Style.FILL);
+ protected static void drawShadows(Canvas canvas, Paint p, RectF innerBounds, RectF outerBounds,
+ float rotation, float centerX, float centerY) {
+ canvas.save();
+ canvas.rotate(rotation, centerX, centerY);
- canvas.drawRect(0, 0, dWidth, innerBounds.top, p);
- canvas.drawRect(0, innerBounds.bottom, dWidth, dHeight, p);
- canvas.drawRect(0, innerBounds.top, innerBounds.left, innerBounds.bottom,
+ float x = (outerBounds.left - outerBounds.right);
+ float y = (outerBounds.top - outerBounds.bottom);
+ float longest = (float) Math.sqrt(x * x + y * y) / 2;
+ float minX = centerX - longest;
+ float maxX = centerX + longest;
+ float minY = centerY - longest;
+ float maxY = centerY + longest;
+ canvas.drawRect(minX, minY, innerBounds.right, innerBounds.top, p);
+ canvas.drawRect(minX, innerBounds.top, innerBounds.left, maxY, p);
+ canvas.drawRect(innerBounds.left, innerBounds.bottom, maxX, maxY,
p);
- canvas.drawRect(innerBounds.right, innerBounds.top, dWidth,
+ canvas.drawRect(innerBounds.right, minY, maxX,
innerBounds.bottom, p);
+ canvas.rotate(-rotation, centerX, centerY);
+ canvas.restore();
}
@Override
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java b/src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java
index a94d6292f..2fd6b9b35 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java
@@ -24,6 +24,8 @@ import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
+import com.android.gallery3d.filtershow.imageshow.ImageGeometry.MODES;
+
public class ImageStraighten extends ImageGeometry {
private float mBaseAngle = 0;
@@ -46,11 +48,17 @@ public class ImageStraighten extends ImageGeometry {
mBaseAngle = mAngle = getLocalStraighten();
}
+ private void setCropToStraighten(){
+ setLocalCropBounds(getUntranslatedStraightenCropBounds(getLocalPhotoBounds(),
+ getLocalStraighten()));
+ }
+
@Override
protected void setActionMove(float x, float y) {
super.setActionMove(x, y);
computeValue();
setLocalStraighten(mAngle);
+ setCropToStraighten();
}
private float angleFor(float dx, float dy) {
@@ -80,6 +88,17 @@ public class ImageStraighten extends ImageGeometry {
}
@Override
+ protected void gainedVisibility(){
+ setCropToStraighten();
+ }
+
+ @Override
+ protected void setActionUp() {
+ super.setActionUp();
+ setCropToStraighten();
+ }
+
+ @Override
public void onNewValue(int value) {
setLocalStraighten(clamp(value, MIN_STRAIGHTEN_ANGLE, MAX_STRAIGHTEN_ANGLE));
if (getPanelController() != null) {
@@ -98,7 +117,7 @@ public class ImageStraighten extends ImageGeometry {
drawTransformedBitmap(canvas, image, gPaint, false);
// Draw the grid
- RectF bounds = cropBounds(image);
+ RectF bounds = straightenBounds();
Path path = new Path();
path.addRect(bounds, Path.Direction.CCW);
gPaint.setARGB(255, 255, 255, 255);