summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRuben Brunk <rubenbrunk@google.com>2012-10-22 03:50:38 -0700
committerRuben Brunk <rubenbrunk@google.com>2012-10-23 16:44:29 -0700
commit95a94afb783be6f01dac6c6c99ab3716cc456ca7 (patch)
tree8872ae4a923b243627cb27dea544a82426d82ecd /src
parent70d8bce63b966a00447f8dbd1736fe26a62b07ac (diff)
downloadandroid_packages_apps_Snap-95a94afb783be6f01dac6c6c99ab3716cc456ca7.tar.gz
android_packages_apps_Snap-95a94afb783be6f01dac6c6c99ab3716cc456ca7.tar.bz2
android_packages_apps_Snap-95a94afb783be6f01dac6c6c99ab3716cc456ca7.zip
Reworked crop/transform UI.
Bug: 7385644 Bug: 7378335 Bug: 7366075 Change-Id: Iee7e0a0741b69269b08726bad45e29d86834054e
Diffstat (limited to 'src')
-rw-r--r--src/com/android/gallery3d/filtershow/PanelController.java79
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java14
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/GeometryMath.java44
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java169
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageCrop.java34
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageFlip.java2
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java64
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageRotate.java2
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageShow.java2
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java4
10 files changed, 290 insertions, 124 deletions
diff --git a/src/com/android/gallery3d/filtershow/PanelController.java b/src/com/android/gallery3d/filtershow/PanelController.java
index 2bf95e759..8f1bdb416 100644
--- a/src/com/android/gallery3d/filtershow/PanelController.java
+++ b/src/com/android/gallery3d/filtershow/PanelController.java
@@ -139,14 +139,7 @@ public class PanelController implements OnClickListener {
private boolean mShowParameterValue = false;
private View mAspectButton = null;
private View mCurvesButton = null;
- private int mCurrentAspectButton = 0;
- private static final int NUMBER_OF_ASPECT_BUTTONS = 6;
- private static final int ASPECT_NONE = 0;
- private static final int ASPECT_1TO1 = 1;
- private static final int ASPECT_5TO7 = 2;
- private static final int ASPECT_4TO6 = 3;
- private static final int ASPECT_16TO9 = 4;
- private static final int ASPECT_ORIG = 5;
+ boolean firstTimeCropDisplayed = true;
public UtilityPanel(Context context, View view, View textView,
View aspectButton, View curvesButton) {
@@ -198,69 +191,6 @@ public class PanelController implements OnClickListener {
imageCrop.invalidate();
}
- public void nextAspectButton() {
- if (mAspectButton instanceof ImageButtonTitle
- && mCurrentImage instanceof ImageCrop) {
- switch (mCurrentAspectButton) {
- case ASPECT_NONE:
- ((ImageButtonTitle) mAspectButton).setText(mContext
- .getString(R.string.aspect)
- + " "
- + mContext.getString(R.string.aspect1to1_effect));
- ((ImageCrop) mCurrentImage).apply(1, 1);
- break;
- case ASPECT_1TO1:
- ((ImageButtonTitle) mAspectButton).setText(mContext
- .getString(R.string.aspect)
- + " "
- + mContext.getString(R.string.aspect5to7_effect));
- ((ImageCrop) mCurrentImage).apply(7, 5);
- break;
- case ASPECT_5TO7:
- ((ImageButtonTitle) mAspectButton).setText(mContext
- .getString(R.string.aspect)
- + " "
- + mContext.getString(R.string.aspect4to6_effect));
- ((ImageCrop) mCurrentImage).apply(6, 4);
- break;
- case ASPECT_4TO6:
- ((ImageButtonTitle) mAspectButton).setText(mContext
- .getString(R.string.aspect)
- + " "
- + mContext.getString(R.string.aspect9to16_effect));
- ((ImageCrop) mCurrentImage).apply(16, 9);
- break;
- case ASPECT_16TO9:
- ((ImageButtonTitle) mAspectButton).setText(mContext
- .getString(R.string.aspect)
- + " "
- + mContext.getString(R.string.aspectOriginal_effect));
- ((ImageCrop) mCurrentImage).applyOriginal();
- break;
- case ASPECT_ORIG:
- ((ImageButtonTitle) mAspectButton).setText(mContext
- .getString(R.string.aspect)
- + " "
- + mContext.getString(R.string.aspectNone_effect));
- ((ImageCrop) mCurrentImage).applyClear();
- break;
- default:
- ((ImageButtonTitle) mAspectButton).setText(mContext
- .getString(R.string.aspect)
- + " "
- + mContext.getString(R.string.aspectNone_effect));
- ((ImageCrop) mCurrentImage).applyClear();
- mCurrentAspectButton = ASPECT_NONE;
- break;
- }
- mCurrentAspectButton = (mCurrentAspectButton + 1) % NUMBER_OF_ASPECT_BUTTONS;
- }
- }
-
- void setCurrentAspectButton(int n) {
- mCurrentAspectButton = n;
- }
-
public void showAspectButtons() {
if (mAspectButton != null)
mAspectButton.setVisibility(View.VISIBLE);
@@ -653,8 +583,10 @@ public class PanelController implements OnClickListener {
String ename = mCurrentImage.getContext().getString(R.string.crop);
mUtilityPanel.setEffectName(ename);
mUtilityPanel.setShowParameter(false);
- mUtilityPanel.setCurrentAspectButton(-1);
- mUtilityPanel.nextAspectButton();
+ if (mCurrentImage instanceof ImageCrop && mUtilityPanel.firstTimeCropDisplayed){
+ ((ImageCrop) mCurrentImage).applyOriginal();
+ mUtilityPanel.firstTimeCropDisplayed = false;
+ }
mUtilityPanel.showAspectButtons();
break;
}
@@ -760,7 +692,6 @@ public class PanelController implements OnClickListener {
break;
}
case R.id.aspect: {
- mUtilityPanel.nextAspectButton();
mUtilityPanel.showAspectButtons();
break;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java
index 04057681f..bdcb0ea4e 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java
@@ -23,6 +23,7 @@ import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
+import com.android.gallery3d.filtershow.imageshow.GeometryMath;
import com.android.gallery3d.filtershow.imageshow.GeometryMetadata;
public class ImageFilterGeometry extends ImageFilter {
@@ -78,19 +79,18 @@ public class ImageFilterGeometry extends ImageFilter {
} else {
temp = Bitmap.createBitmap(cropBounds.width(), cropBounds.height(), mConfig);
}
+ float[] displayCenter = {
+ temp.getWidth() / 2f, temp.getHeight() / 2f
+ };
+
+ Matrix m1 = mGeometry.buildTotalXform(bitmap.getWidth(), bitmap.getHeight(), displayCenter);
- RectF rp = mGeometry.getPhotoBounds();
- RectF rc = mGeometry.getPreviewCropBounds();
- Matrix drawMatrix = mGeometry.buildTotalXform(rp.width(), rp.height(), rc.width(),
- rc.height(), rc.left, rc.top,
- mGeometry.getRotation(), mGeometry.getStraightenRotation(),
- bitmap.getWidth() / rp.width(), null);
Canvas canvas = new Canvas(temp);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
- canvas.drawBitmap(bitmap, drawMatrix, paint);
+ canvas.drawBitmap(bitmap, m1, paint);
return temp;
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/GeometryMath.java b/src/com/android/gallery3d/filtershow/imageshow/GeometryMath.java
index 3f9d4fa28..d27946a91 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/GeometryMath.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/GeometryMath.java
@@ -16,8 +16,12 @@
package com.android.gallery3d.filtershow.imageshow;
+import android.graphics.RectF;
+
public class GeometryMath {
- protected static float clamp(float i, float low, float high) {
+
+ // Math operations for 2d vectors
+ public static float clamp(float i, float low, float high) {
return Math.max(Math.min(i, high), low);
}
@@ -35,36 +39,58 @@ public class GeometryMath {
float[] ret = {
(x1 + u * (x2 - x1)), (y1 + u * (y2 - y1))
};
- return ret;
+ float [] vec = {ret[0] - point[0], ret[1] - point[1] };
+ return vec;
}
- //A . B
- protected static float dotProduct(float[] a, float[] b){
+ // A . B
+ public static float dotProduct(float[] a, float[] b){
return a[0] * b[0] + a[1] * b[1];
}
- protected static float[] normalize(float[] a){
+ public static float[] normalize(float[] a){
float length = (float) Math.sqrt(a[0] * a[0] + a[1] * a[1]);
float[] b = { a[0] / length, a[1] / length };
return b;
}
- //A onto B
- protected static float scalarProjection(float[] a, float[] b){
+ // A onto B
+ public static float scalarProjection(float[] a, float[] b){
float length = (float) Math.sqrt(b[0] * b[0] + b[1] * b[1]);
return dotProduct(a, b) / length;
}
- protected static float[] getVectorFromPoints(float [] point1, float [] point2){
+ public static float[] getVectorFromPoints(float [] point1, float [] point2){
float [] p = { point2[0] - point1[0], point2[1] - point1[1] };
return p;
}
- protected static float[] getUnitVectorFromPoints(float [] point1, float [] point2){
+ public static float[] getUnitVectorFromPoints(float [] point1, float [] point2){
float [] p = { point2[0] - point1[0], point2[1] - point1[1] };
float length = (float) Math.sqrt(p[0] * p[0] + p[1] * p[1]);
p[0] = p[0] / length;
p[1] = p[1] / length;
return p;
}
+
+ public static RectF scaleRect(RectF r, float scale){
+ return new RectF(r.left * scale, r.top * scale, r.right * scale, r.bottom * scale);
+ }
+
+ // A - B
+ public static float[] vectorSubtract(float [] a, float [] b){
+ int len = a.length;
+ if (len != b.length)
+ return null;
+ float [] ret = new float[len];
+ for (int i = 0; i < len; i++){
+ ret[i] = a[i] - b[i];
+ }
+ return ret;
+ }
+
+ public static float vectorLength(float [] a){
+ return (float) Math.sqrt(a[0] * a[0] + a[1] * a[1]);
+ }
+
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java b/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java
index 58c6f6fde..897c8cb84 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java
@@ -22,6 +22,8 @@ import android.graphics.RectF;
import com.android.gallery3d.filtershow.filters.ImageFilterGeometry;
+import java.util.Arrays;
+
public class GeometryMetadata {
// Applied in order: rotate, crop, scale.
// Do not scale saved image (presumably?).
@@ -178,22 +180,34 @@ public class GeometryMetadata {
+ ",photoRect=" + mPhotoBounds.toShortString() + "]";
}
- protected Matrix getHorizontalMatrix(float width) {
+ // TODO: refactor away
+ protected static Matrix getHorizontalMatrix(float width) {
Matrix flipHorizontalMatrix = new Matrix();
flipHorizontalMatrix.setScale(-1, 1);
flipHorizontalMatrix.postTranslate(width, 0);
return flipHorizontalMatrix;
}
- protected Matrix getVerticalMatrix(float height) {
+ protected static void concatHorizontalMatrix(Matrix m, float width) {
+ m.postScale(-1, 1);
+ m.postTranslate(width, 0);
+ }
+
+ // TODO: refactor away
+ protected static Matrix getVerticalMatrix(float height) {
Matrix flipVerticalMatrix = new Matrix();
flipVerticalMatrix.setScale(1, -1);
flipVerticalMatrix.postTranslate(0, height);
return flipVerticalMatrix;
}
- public Matrix getFlipMatrix(float width, float height) {
- FLIP type = getFlipType();
+ protected static void concatVerticalMatrix(Matrix m, float height) {
+ m.postScale(1, -1);
+ m.postTranslate(0, height);
+ }
+
+ // TODO: refactor away
+ public static Matrix getFlipMatrix(float width, float height, FLIP type) {
if (type == FLIP.HORIZONTAL) {
return getHorizontalMatrix(width);
} else if (type == FLIP.VERTICAL) {
@@ -209,10 +223,28 @@ public class GeometryMetadata {
}
}
+ public static void concatMirrorMatrix(Matrix m, float width, float height, FLIP type) {
+ if (type == FLIP.HORIZONTAL) {
+ concatHorizontalMatrix(m, width);
+ } else if (type == FLIP.VERTICAL) {
+ concatVerticalMatrix(m, height);
+ } else if (type == FLIP.BOTH) {
+ concatVerticalMatrix(m, height);
+ concatHorizontalMatrix(m, width);
+ }
+ }
+
+ // TODO: refactor away
+ public Matrix getFlipMatrix(float width, float height) {
+ FLIP type = getFlipType();
+ return getFlipMatrix(width, height, type);
+ }
+
public boolean hasSwitchedWidthHeight() {
return (((int) (mRotation / 90)) % 2) != 0;
}
+ // TODO: refactor away
public Matrix buildGeometryMatrix(float width, float height, float scaling, float dx, float dy,
float rotation) {
float dx0 = width / 2;
@@ -225,6 +257,7 @@ public class GeometryMetadata {
return m;
}
+ // TODO: refactor away
public Matrix buildGeometryMatrix(float width, float height, float scaling, float dx, float dy,
boolean onlyRotate) {
float rot = mRotation;
@@ -234,28 +267,124 @@ public class GeometryMetadata {
return buildGeometryMatrix(width, height, scaling, dx, dy, rot);
}
+ // TODO: refactor away
public Matrix buildGeometryUIMatrix(float scaling, float dx, float dy) {
float w = mPhotoBounds.width();
float h = mPhotoBounds.height();
return buildGeometryMatrix(w, h, scaling, dx, dy, false);
}
- public Matrix buildTotalXform(float pwidth, float pheight, float cwidth, float cheight,
- float cleft, float ctop, float rotation, float straighten, float scale, RectF dst) {
- float s_pwidth = pwidth * scale;
- float s_pheight = pheight * scale;
- Matrix m = getFlipMatrix(s_pwidth, s_pheight);
- m.postRotate(rotation + straighten, s_pwidth / 2, s_pheight / 2);
- Matrix m1 = getFlipMatrix(s_pwidth, s_pheight);
- m1.postRotate(rotation, s_pwidth / 2, s_pheight / 2);
- // find new top left for crop.
- RectF crop = new RectF(cleft * scale, ctop * scale, (cleft + cwidth) * scale,
- (ctop + cheight) * scale);
- if (!m1.mapRect(crop))
- return null;
- if (dst != null)
- dst.set(crop);
- m.postTranslate(-crop.left, -crop.top);
+ public static Matrix buildPhotoMatrix(RectF photo, RectF crop, float rotation,
+ float straighten, FLIP type) {
+ Matrix m = new Matrix();
+ m.setRotate(straighten, photo.centerX(), photo.centerY());
+ concatMirrorMatrix(m, photo.right, photo.bottom, type);
+ m.postRotate(rotation, crop.centerX(), crop.centerY());
+
+ return m;
+ }
+
+ public static Matrix buildCropMatrix(RectF crop, float rotation) {
+ Matrix m = new Matrix();
+ m.setRotate(rotation, crop.centerX(), crop.centerY());
+ return m;
+ }
+
+ public static void concatRecenterMatrix(Matrix m, float[] currentCenter, float[] newCenter) {
+ m.postTranslate(newCenter[0] - currentCenter[0], newCenter[1] - currentCenter[1]);
+ }
+
+ /**
+ * Builds a matrix to transform a bitmap of width bmWidth and height
+ * bmHeight so that the region of the bitmap being cropped to is
+ * oriented and centered at displayCenter.
+ *
+ * @param bmWidth
+ * @param bmHeight
+ * @param displayCenter
+ * @return
+ */
+ public Matrix buildTotalXform(float bmWidth, float bmHeight, float[] displayCenter) {
+ RectF rp = getPhotoBounds();
+ RectF rc = getPreviewCropBounds();
+
+ float scale = bmWidth / rp.width();
+ RectF scaledCrop = GeometryMath.scaleRect(rc, scale);
+ RectF scaledPhoto = GeometryMath.scaleRect(rp, scale);
+
+ Matrix m1 = GeometryMetadata.buildWanderingCropMatrix(scaledPhoto, scaledCrop,
+ getRotation(), getStraightenRotation(),
+ getFlipType(), displayCenter);
+ float[] cropCenter = {
+ scaledCrop.centerX(), scaledCrop.centerY()
+ };
+ m1.mapPoints(cropCenter);
+
+ GeometryMetadata.concatRecenterMatrix(m1, cropCenter, displayCenter);
+ m1.preRotate(getStraightenRotation(), scaledPhoto.centerX(),
+ scaledPhoto.centerY());
+ return m1;
+ }
+
+ /**
+ * Builds a matrix that rotates photo rect about it's center by the
+ * straighten angle, mirrors it about the crop center, and rotates it about
+ * the crop center by the rotation angle, and re-centers the photo rect.
+ *
+ * @param photo
+ * @param crop
+ * @param rotation
+ * @param straighten
+ * @param type
+ * @param newCenter
+ * @return
+ */
+ public static Matrix buildCenteredPhotoMatrix(RectF photo, RectF crop, float rotation,
+ float straighten, FLIP type, float[] newCenter) {
+ Matrix m = buildPhotoMatrix(photo, crop, rotation, straighten, type);
+ float[] center = {
+ photo.centerX(), photo.centerY()
+ };
+ m.mapPoints(center);
+ concatRecenterMatrix(m, center, newCenter);
+ return m;
+ }
+
+ /**
+ * Builds a matrix that rotates a crop rect about it's center by rotation
+ * angle, then re-centers the crop rect.
+ *
+ * @param crop
+ * @param rotation
+ * @param newCenter
+ * @return
+ */
+ public static Matrix buildCenteredCropMatrix(RectF crop, float rotation, float[] newCenter) {
+ Matrix m = buildCropMatrix(crop, rotation);
+ float[] center = {
+ crop.centerX(), crop.centerY()
+ };
+ m.mapPoints(center);
+ concatRecenterMatrix(m, center, newCenter);
+ return m;
+ }
+
+ /**
+ * Builds a matrix that transforms the crop rect to its view coordinates
+ * inside the photo rect.
+ *
+ * @param photo
+ * @param crop
+ * @param rotation
+ * @param straighten
+ * @param type
+ * @param newCenter
+ * @return
+ */
+ public static Matrix buildWanderingCropMatrix(RectF photo, RectF crop, float rotation,
+ float straighten, FLIP type, float[] newCenter) {
+ Matrix m = buildCenteredPhotoMatrix(photo, crop, rotation, straighten, type, newCenter);
+ m.preRotate(-straighten, photo.centerX(), photo.centerY());
return m;
}
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageCrop.java b/src/com/android/gallery3d/filtershow/imageshow/ImageCrop.java
index c740977bb..f0c520ae6 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageCrop.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageCrop.java
@@ -52,6 +52,7 @@ public class ImageCrop extends ImageGeometry {
private float mAspectHeight = 1;
private boolean mFixAspectRatio = false;
+ private float mLastRot = 0;
private final Paint borderPaint;
private int movingEdges;
@@ -90,6 +91,12 @@ public class ImageCrop extends ImageGeometry {
return getContext().getString(R.string.crop);
}
+ private void swapAspect(){
+ float temp = mAspectWidth;
+ mAspectWidth = mAspectHeight;
+ mAspectHeight = temp;
+ }
+
private boolean switchCropBounds(int moving_corner, RectF dst) {
RectF crop = getCropBoundsDisplayed();
float dx1 = 0;
@@ -144,9 +151,7 @@ public class ImageCrop extends ImageGeometry {
Log.v(LOGTAG, "FAILED TO MAP RECTANGLE TO RECTANGLE");
return false;
}
- float temp = mAspectWidth;
- mAspectWidth = mAspectHeight;
- mAspectHeight = temp;
+ swapAspect();
dst.set(newCrop);
return true;
}
@@ -565,6 +570,11 @@ public class ImageCrop extends ImageGeometry {
@Override
protected void gainedVisibility() {
+ float rot = getLocalRotation();
+ // if has changed orientation via rotate
+ if( ((int) ((rot - mLastRot) / 90)) % 2 != 0 ){
+ swapAspect();
+ }
cropSetup();
mFirstDraw = true;
}
@@ -577,19 +587,20 @@ public class ImageCrop extends ImageGeometry {
@Override
protected void lostVisibility() {
+ mLastRot = getLocalRotation();
}
- private void drawRuleOfThird(Canvas canvas, RectF bounds) {
+ private void drawRuleOfThird(Canvas canvas, RectF bounds, Paint p) {
float stepX = bounds.width() / 3.0f;
float stepY = bounds.height() / 3.0f;
float x = bounds.left + stepX;
float y = bounds.top + stepY;
for (int i = 0; i < 2; i++) {
- canvas.drawLine(x, bounds.top, x, bounds.bottom, gPaint);
+ canvas.drawLine(x, bounds.top, x, bounds.bottom, p);
x += stepX;
}
for (int j = 0; j < 2; j++) {
- canvas.drawLine(bounds.left, y, bounds.right, y, gPaint);
+ canvas.drawLine(bounds.left, y, bounds.right, y, p);
y += stepY;
}
}
@@ -607,17 +618,22 @@ public class ImageCrop extends ImageGeometry {
mFirstDraw = false;
}
float rotation = getLocalRotation();
- drawTransformedBitmap(canvas, image, gPaint, true);
+
+ RectF crop = drawTransformed(canvas, image, gPaint);
+ gPaint.setColor(mBorderColor);
+ gPaint.setStrokeWidth(3);
+ gPaint.setStyle(Paint.Style.STROKE);
+ drawRuleOfThird(canvas, crop, gPaint);
gPaint.setColor(mBorderColor);
gPaint.setStrokeWidth(3);
gPaint.setStyle(Paint.Style.STROKE);
drawStraighten(canvas, gPaint);
- RectF scaledCrop = unrotatedCropBounds();
- drawRuleOfThird(canvas, scaledCrop);
+
int decoded_moving = decoder(movingEdges, rotation);
canvas.save();
canvas.rotate(rotation, mCenterX, mCenterY);
+ RectF scaledCrop = unrotatedCropBounds();
boolean notMoving = decoded_moving == 0;
if (((decoded_moving & MOVE_TOP) != 0) || notMoving) {
drawIndicator(canvas, cropIndicator, scaledCrop.centerX(), scaledCrop.top);
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageFlip.java b/src/com/android/gallery3d/filtershow/imageshow/ImageFlip.java
index 931ef86d2..5d6fe502f 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageFlip.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageFlip.java
@@ -139,7 +139,7 @@ public class ImageFlip extends ImageGeometry {
gPaint.setFilterBitmap(true);
gPaint.setDither(true);
gPaint.setARGB(255, 255, 255, 255);
- drawTransformedBitmap(canvas, image, gPaint, false);
+ drawTransformedCropped(canvas, image, gPaint);
}
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java b/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java
index 6bdbeb815..590b53cd6 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java
@@ -221,6 +221,7 @@ public abstract class ImageGeometry extends ImageSlave {
return getLocalRotation() + getLocalStraighten();
}
+
protected static float[] getCornersFromRect(RectF r) {
// Order is:
// 0------->1
@@ -542,4 +543,67 @@ public abstract class ImageGeometry extends ImageSlave {
protected void drawShape(Canvas canvas, Bitmap image) {
// TODO: Override this stub.
}
+
+ protected RectF drawTransformed(Canvas canvas, Bitmap photo, Paint p){
+ p.setARGB(255, 0, 0, 0);
+ RectF photoBounds = getLocalPhotoBounds();
+ RectF cropBounds = getLocalCropBounds();
+ float scale = computeScale(getWidth(), getHeight());
+ // put in screen coordinates
+ RectF scaledCrop = GeometryMath.scaleRect(cropBounds, scale);
+ RectF scaledPhoto = GeometryMath.scaleRect(photoBounds, scale);
+ float [] displayCenter = { getWidth() / 2f, getHeight() / 2f };
+ Matrix m = GeometryMetadata.buildCenteredPhotoMatrix(scaledPhoto, scaledCrop,
+ getLocalRotation(), getLocalStraighten(), getLocalFlip(), displayCenter);
+
+ Matrix m1 = GeometryMetadata.buildWanderingCropMatrix(scaledPhoto, scaledCrop,
+ getLocalRotation(), getLocalStraighten(), getLocalFlip(), displayCenter);
+ m1.mapRect(scaledCrop);
+ Path path = new Path();
+ path.addRect(scaledCrop, Path.Direction.CCW);
+
+ m.preScale(scale, scale);
+ canvas.save();
+ canvas.drawBitmap(photo, m, p);
+ canvas.restore();
+
+ p.setColor(Color.WHITE);
+ p.setStyle(Style.STROKE);
+ p.setStrokeWidth(2);
+ canvas.drawPath(path, p);
+ return scaledCrop;
+ }
+
+ protected void drawTransformedCropped(Canvas canvas, Bitmap photo, Paint p){
+ RectF photoBounds = getLocalPhotoBounds();
+ RectF cropBounds = getLocalCropBounds();
+ float imageWidth = cropBounds.width();
+ float imageHeight = cropBounds.height();
+ float scale = getWidth() / imageWidth;
+ if (imageHeight > imageWidth) {
+ scale = getHeight() / imageHeight;
+ }
+ // put in screen coordinates
+ RectF scaledCrop = GeometryMath.scaleRect(cropBounds, scale);
+ RectF scaledPhoto = GeometryMath.scaleRect(photoBounds, scale);
+ float [] displayCenter = { getWidth() / 2f, getHeight() / 2f };
+ Matrix m1 = GeometryMetadata.buildWanderingCropMatrix(scaledPhoto, scaledCrop,
+ getLocalRotation(), getLocalStraighten(), getLocalFlip(), displayCenter);
+ float [] cropCenter = { scaledCrop.centerX(), scaledCrop.centerY() };
+ m1.mapPoints(cropCenter);
+ GeometryMetadata.concatRecenterMatrix(m1, cropCenter, displayCenter);
+ m1.preRotate(getLocalStraighten(), scaledPhoto.centerX(), scaledPhoto.centerY());
+ m1.preScale(scale, scale);
+
+ p.setARGB(255, 0, 0, 0);
+ canvas.save();
+ canvas.drawBitmap(photo, m1, p);
+ canvas.restore();
+
+ p.setARGB(255, 0, 0, 0);
+ p.setStyle(Paint.Style.FILL);
+ scaledCrop.offset(displayCenter[0] - scaledCrop.centerX(), displayCenter[1]
+ - scaledCrop.centerY());
+ drawShadows(canvas, p, scaledCrop);
+ }
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageRotate.java b/src/com/android/gallery3d/filtershow/imageshow/ImageRotate.java
index 0d458ca45..90bbeaacd 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageRotate.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageRotate.java
@@ -84,6 +84,6 @@ public class ImageRotate extends ImageGeometry {
gPaint.setFilterBitmap(true);
gPaint.setDither(true);
gPaint.setARGB(255, 255, 255, 255);
- drawTransformedBitmap(canvas, image, gPaint, true);
+ drawTransformedCropped(canvas, image, gPaint);
}
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java b/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java
index 72c594c85..b15723702 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java
@@ -64,7 +64,7 @@ public class ImageShow extends View implements OnGestureListener,
protected ImageLoader mImageLoader = null;
private ImageFilter mCurrentFilter = null;
- private boolean mDirtyGeometry = true;
+ private boolean mDirtyGeometry = false;
private Bitmap mBackgroundImage = null;
private final boolean USE_BACKGROUND_IMAGE = false;
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java b/src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java
index 0f70b23ed..57a22aab3 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java
@@ -19,6 +19,7 @@ package com.android.gallery3d.filtershow.imageshow;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
@@ -33,7 +34,6 @@ public class ImageStraighten extends ImageGeometry {
private static final String LOGTAG = "ImageStraighten";
private static final Paint gPaint = new Paint();
-
public ImageStraighten(Context context) {
super(context);
}
@@ -105,7 +105,7 @@ public class ImageStraighten extends ImageGeometry {
@Override
protected void drawShape(Canvas canvas, Bitmap image) {
- drawTransformedBitmap(canvas, image, gPaint, false);
+ drawTransformed(canvas, image, gPaint);
// Draw the grid
RectF bounds = straightenBounds();