summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--jni/filters/vignette.c44
-rw-r--r--res/layout/filtershow_vignette_editor.xml46
-rw-r--r--res/values/filtershow_ids.xml1
-rw-r--r--src/com/android/gallery3d/filtershow/editors/EditorVignette.java55
-rw-r--r--src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java114
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java60
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java252
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImagePoint.java10
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageRedEye.java12
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageShow.java29
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageTinyPlanet.java5
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageVignette.java127
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/Oval.java29
-rw-r--r--src_pd/com/android/gallery3d/filtershow/editors/EditorManager.java1
14 files changed, 714 insertions, 71 deletions
diff --git a/jni/filters/vignette.c b/jni/filters/vignette.c
index 2799ff001..b9ee3ff01 100644
--- a/jni/filters/vignette.c
+++ b/jni/filters/vignette.c
@@ -15,52 +15,32 @@
*/
#include "filters.h"
+#include <math.h>
static int* gVignetteMap = 0;
static int gVignetteWidth = 0;
static int gVignetteHeight = 0;
-__inline__ void createVignetteMap(int w, int h)
-{
- if (gVignetteMap && (gVignetteWidth != w || gVignetteHeight != h))
- {
- free(gVignetteMap);
- gVignetteMap = 0;
- }
- if (gVignetteMap == 0)
- {
- gVignetteWidth = w;
- gVignetteHeight = h;
-
- int cx = w / 2;
- int cy = h / 2;
- int i, j;
-
- gVignetteMap = malloc(w * h * sizeof(int));
- float maxDistance = cx * cx * 2.0f;
- for (i = 0; i < w; i++)
- {
- for (j = 0; j < h; j++)
- {
- float distance = (cx - i) * (cx - i) + (cy - j) * (cy - j);
- gVignetteMap[j * w + i] = (int) (distance / maxDistance * 255);
- }
- }
- }
-}
-
-void JNIFUNCF(ImageFilterVignette, nativeApplyFilter, jobject bitmap, jint width, jint height, jfloat strength)
+void JNIFUNCF(ImageFilterVignette, nativeApplyFilter, jobject bitmap, jint width, jint height, jint centerx, jint centery, jfloat radiusx, jfloat radiusy, jfloat strength)
{
char* destination = 0;
AndroidBitmap_lockPixels(env, bitmap, (void**) &destination);
- createVignetteMap(width, height);
int i;
int len = width * height * 4;
int vignette = 0;
+ float d = centerx;
+ if (radiusx == 0) radiusx = 10;
+ if (radiusy == 0) radiusy = 10;
+ float scalex = 1/radiusx;
+ float scaley = 1/radiusy;
for (i = 0; i < len; i += 4)
{
- vignette = (int) (strength * gVignetteMap[i / 4]);
+ int p = i/4;
+ float x = ((p%width)-centerx)*scalex;
+ float y = ((p/width)-centery)*scaley;
+ float dist = sqrt(x*x+y*y)-1;
+ vignette = (int) (strength*256*MAX(dist,0));
destination[RED] = CLAMP(destination[RED] - vignette);
destination[GREEN] = CLAMP(destination[GREEN] - vignette);
destination[BLUE] = CLAMP(destination[BLUE] - vignette);
diff --git a/res/layout/filtershow_vignette_editor.xml b/res/layout/filtershow_vignette_editor.xml
new file mode 100644
index 000000000..6e5755928
--- /dev/null
+++ b/res/layout/filtershow_vignette_editor.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:iconbutton="http://schemas.android.com/apk/res/com.android.gallery3d"
+ android:id="@+id/tinyPlanetEditor"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1" >
+
+ <com.android.gallery3d.filtershow.imageshow.ImageVignette
+ android:id="@+id/imageVignette"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <com.android.gallery3d.filtershow.CenteredLinearLayout
+ xmlns:custom="http://schemas.android.com/apk/res/com.android.gallery3d"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal|bottom"
+ android:background="@android:color/transparent"
+ custom:max_width="600dip"
+ android:orientation="vertical">
+
+ <SeekBar
+ android:id="@+id/filterSeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:padding="16dip"/>
+ </com.android.gallery3d.filtershow.CenteredLinearLayout>
+ </FrameLayout> \ No newline at end of file
diff --git a/res/values/filtershow_ids.xml b/res/values/filtershow_ids.xml
index 786d7ee7d..ba318345b 100644
--- a/res/values/filtershow_ids.xml
+++ b/res/values/filtershow_ids.xml
@@ -40,4 +40,5 @@
<item type="id" name="editorDraw" />
<item type="id" name="editorRedEye" />
<item type="id" name="imageOnlyEditor" />
+ <item type="id" name="vignetteEditor" />
</resources>
diff --git a/src/com/android/gallery3d/filtershow/editors/EditorVignette.java b/src/com/android/gallery3d/filtershow/editors/EditorVignette.java
new file mode 100644
index 000000000..a60c1681e
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/editors/EditorVignette.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.filtershow.editors;
+
+import android.content.Context;
+import android.util.Log;
+import android.widget.FrameLayout;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.filters.FilterRepresentation;
+import com.android.gallery3d.filtershow.filters.FilterTinyPlanetRepresentation;
+import com.android.gallery3d.filtershow.filters.FilterVignetteRepresentation;
+import com.android.gallery3d.filtershow.imageshow.ImageVignette;
+
+public class EditorVignette extends BasicEditor {
+ public static final int ID = R.id.vignetteEditor;
+ private static final String LOGTAG = "EditorVignettePlanet";
+ ImageVignette mImageVignette;
+
+ public EditorVignette() {
+ super(ID, R.layout.filtershow_vignette_editor, R.id.imageVignette);
+ }
+
+ @Override
+ public void createEditor(Context context, FrameLayout frameLayout) {
+ super.createEditor(context, frameLayout);
+ mImageVignette = (ImageVignette) mImageShow;
+ mImageVignette.setEditor(this);
+ }
+
+ @Override
+ public void reflectCurrentFilter() {
+ super.reflectCurrentFilter();
+
+ FilterRepresentation rep = getLocalRepresentation();
+ if (rep != null && getLocalRepresentation() instanceof FilterVignetteRepresentation) {
+ FilterVignetteRepresentation drawRep = (FilterVignetteRepresentation) rep;
+ mImageVignette.setRepresentation(drawRep);
+ }
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java
new file mode 100644
index 000000000..eef54ef58
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.filtershow.filters;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.editors.EditorVignette;
+import com.android.gallery3d.filtershow.imageshow.Oval;
+
+public class FilterVignetteRepresentation extends FilterBasicRepresentation implements Oval {
+ private static final String LOGTAG = "FilterVignetteRepresentation";
+ private float mCenterX = Float.NaN;
+ private float mCenterY;
+ private float mRadiusX = Float.NaN;
+ private float mRadiusY;
+
+ public FilterVignetteRepresentation() {
+ super("Vignette", -100, 50, 100);
+ setShowParameterValue(true);
+ setPriority(FilterRepresentation.TYPE_VIGNETTE);
+ setTextId(R.string.vignette);
+ setButtonId(R.id.vignetteEditor);
+ setEditorId(EditorVignette.ID);
+ setName("Vignette");
+ setFilterClass(ImageFilterVignette.class);
+
+ setMinimum(-100);
+ setMaximum(100);
+ setDefaultValue(0);
+ }
+
+ @Override
+ public void useParametersFrom(FilterRepresentation a) {
+ super.useParametersFrom(a);
+ mCenterX = ((FilterVignetteRepresentation) a).mCenterX;
+ mCenterY = ((FilterVignetteRepresentation) a).mCenterY;
+ mRadiusX = ((FilterVignetteRepresentation) a).mRadiusX;
+ mRadiusY = ((FilterVignetteRepresentation) a).mRadiusY;
+ }
+
+ @Override
+ public FilterRepresentation clone() throws CloneNotSupportedException {
+ FilterVignetteRepresentation representation = (FilterVignetteRepresentation) super
+ .clone();
+ representation.mCenterX = mCenterX;
+ representation.mCenterY = mCenterY;
+
+ return representation;
+ }
+
+ @Override
+ public void setCenter(float centerX, float centerY) {
+ mCenterX = centerX;
+ mCenterY = centerY;
+ }
+
+ @Override
+ public float getCenterX() {
+ return mCenterX;
+ }
+
+ @Override
+ public float getCenterY() {
+ return mCenterY;
+ }
+
+ @Override
+ public void setRadius(float radiusX, float radiusY) {
+ mRadiusX = radiusX;
+ mRadiusY = radiusY;
+ }
+
+ @Override
+ public void setRadiusX(float radiusX) {
+ mRadiusX = radiusX;
+ }
+
+ @Override
+ public void setRadiusY(float radiusY) {
+ mRadiusY = radiusY;
+ }
+
+ @Override
+ public float getRadiusX() {
+ return mRadiusX;
+ }
+
+ @Override
+ public float getRadiusY() {
+ return mRadiusY;
+ }
+
+ public boolean isCenterSet() {
+ return mCenterX != Float.NaN;
+ }
+
+ @Override
+ public boolean isNil() {
+ return getValue() == 0;
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java
index 465d90bfd..9ff737e32 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java
@@ -16,47 +16,67 @@
package com.android.gallery3d.filtershow.filters;
-import com.android.gallery3d.R;
-
import android.graphics.Bitmap;
+import android.graphics.Matrix;
+
import com.android.gallery3d.app.Log;
public class ImageFilterVignette extends SimpleImageFilter {
-
private static final String LOGTAG = "ImageFilterVignette";
public ImageFilterVignette() {
mName = "Vignette";
}
+ @Override
public FilterRepresentation getDefaultRepresentation() {
- FilterBasicRepresentation representation =
- (FilterBasicRepresentation) super.getDefaultRepresentation();
- representation.setName("Vignette");
- representation.setFilterClass(ImageFilterVignette.class);
- representation.setPriority(FilterRepresentation.TYPE_VIGNETTE);
- representation.setTextId(R.string.vignette);
- representation.setButtonId(R.id.vignetteButton);
-
- representation.setMinimum(-100);
- representation.setMaximum(100);
- representation.setDefaultValue(0);
-
+ FilterVignetteRepresentation representation = new FilterVignetteRepresentation();
return representation;
}
- native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float strength);
+ native protected void nativeApplyFilter(
+ Bitmap bitmap, int w, int h, int cx, int cy, float radx, float rady, float strength);
+
+ private float calcRadius(float cx, float cy, int w, int h) {
+ float d = cx;
+ if (d < (w - cx)) {
+ d = w - cx;
+ }
+ if (d < cy) {
+ d = cy;
+ }
+ if (d < (h - cy)) {
+ d = h - cy;
+ }
+ return d * d * 2.0f;
+ }
@Override
public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
- if (getParameters() == null) {
+ FilterVignetteRepresentation rep = (FilterVignetteRepresentation) getParameters();
+ if (rep == null) {
return bitmap;
}
int w = bitmap.getWidth();
int h = bitmap.getHeight();
- float value = getParameters().getValue() / 100.0f;
- nativeApplyFilter(bitmap, w, h, value);
-
+ float value = rep.getValue() / 100.0f;
+ float cx = w / 2;
+ float cy = h / 2;
+ float r = calcRadius(cx, cy, w, h);
+ float rx = r;
+ float ry = r;
+ if (rep.isCenterSet()) {
+ Matrix m = getOriginalToScreenMatrix(w, h);
+ cx = rep.getCenterX();
+ cy = rep.getCenterY();
+ float[] center = new float[] { cx, cy };
+ m.mapPoints(center);
+ cx = center[0];
+ cy = center[1];
+ rx = m.mapRadius(rep.getRadiusX());
+ ry = m.mapRadius(rep.getRadiusY());
+ }
+ nativeApplyFilter(bitmap, w, h, (int) cx, (int) cy, rx, ry, value);
return bitmap;
}
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java b/src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java
new file mode 100644
index 000000000..24791887d
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.filtershow.imageshow;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.RectF;
+import android.graphics.Shader;
+
+import com.android.gallery3d.R;
+
+public class EclipseControl {
+ private float mCenterX = Float.NaN;
+ private float mCenterY = 0;
+ private float mRadiusX = 200;
+ private float mRadiusY = 300;
+ private static int MIN_TOUCH_DIST = 80;// should be a resource & in dips
+
+ private float[] handlex = new float[9];
+ private float[] handley = new float[9];
+ private int mSliderColor;
+ private int mCenterDotSize = 40;
+ private float mDownX;
+ private float mDownY;
+ private float mDownCenterX;
+ private float mDownCenterY;
+ private float mDownRadiusX;
+ private float mDownRadiusY;
+ private Matrix mScrToImg;
+
+ private final static int HAN_CENTER = 0;
+ private final static int HAN_NORTH = 7;
+ private final static int HAN_NE = 8;
+ private final static int HAN_EAST = 1;
+ private final static int HAN_SE = 2;
+ private final static int HAN_SOUTH = 3;
+ private final static int HAN_SW = 4;
+ private final static int HAN_WEST = 5;
+ private final static int HAN_NW = 6;
+
+ public EclipseControl(Context context) {
+ mSliderColor = context.getResources().getColor(R.color.slider_line_color);
+ }
+
+ public void setRadius(float x, float y) {
+ mRadiusX = x;
+ mRadiusY = y;
+ }
+
+ public void setCenter(float x, float y) {
+ mCenterX = x;
+ mCenterY = y;
+ }
+
+ public int getCloseHandle(float x, float y) {
+ float min = Float.MAX_VALUE;
+ int handle = -1;
+ for (int i = 0; i < handlex.length; i++) {
+ float dx = handlex[i] - x;
+ float dy = handley[i] - y;
+ float dist = dx * dx + dy * dy;
+ if (dist < min) {
+ min = dist;
+ handle = i;
+ }
+ }
+
+ if (min < MIN_TOUCH_DIST * MIN_TOUCH_DIST) {
+ return handle;
+ }
+ for (int i = 0; i < handlex.length; i++) {
+ float dx = handlex[i] - x;
+ float dy = handley[i] - y;
+ float dist = (float) Math.sqrt(dx * dx + dy * dy);
+ }
+
+ return -1;
+ }
+
+ public void setScrToImageMatrix(Matrix scrToImg) {
+ mScrToImg = scrToImg;
+ }
+
+ public void actionDown(float x, float y, Oval oval) {
+ float[] point = new float[] {
+ x, y };
+ mScrToImg.mapPoints(point);
+ mDownX = point[0];
+ mDownY = point[1];
+ mDownCenterX = oval.getCenterX();
+ mDownCenterY = oval.getCenterY();
+ mDownRadiusX = oval.getRadiusX();
+ mDownRadiusY = oval.getRadiusY();
+ }
+
+ public void actionMove(int handle, float x, float y, Oval oval) {
+ float[] point = new float[] {
+ x, y };
+ mScrToImg.mapPoints(point);
+ x = point[0];
+ y = point[1];
+ int sign = 1;
+ switch (handle) {
+ case HAN_CENTER:
+ float ctrdx = mDownX - mDownCenterX;
+ float ctrdy = mDownY - mDownCenterY;
+ oval.setCenter(x - ctrdx, y - ctrdy);
+ // setRepresentation(mVignetteRep);
+ break;
+ case HAN_NORTH:
+ sign = -1;
+ case HAN_SOUTH:
+ float raddy = mDownRadiusY - Math.abs(mDownY - mDownCenterY);
+ oval.setRadiusY(Math.abs(y - oval.getCenterY() + sign * raddy));
+ break;
+ case HAN_EAST:
+ sign = -1;
+ case HAN_WEST:
+ float raddx = mDownRadiusX - Math.abs(mDownX - mDownCenterX);
+ oval.setRadiusX(Math.abs(x - oval.getCenterX() - sign * raddx));
+ break;
+ case HAN_SE:
+ case HAN_NE:
+ case HAN_SW:
+ case HAN_NW:
+ float sin45 = (float) Math.sin(45);
+ float dr = (mDownRadiusX + mDownRadiusY) * sin45;
+ float ctr_dx = mDownX - mDownCenterX;
+ float ctr_dy = mDownY - mDownCenterY;
+ float downRad = Math.abs(ctr_dx) + Math.abs(ctr_dy) - dr;
+ float rx = oval.getRadiusX();
+ float ry = oval.getRadiusY();
+ float r = (Math.abs(rx) + Math.abs(ry)) * sin45;
+ float dx = x - oval.getCenterX();
+ float dy = y - oval.getCenterY();
+ float nr = Math.abs(Math.abs(dx) + Math.abs(dy) - downRad);
+ oval.setRadius(rx * nr / r, ry * nr / r);
+
+ break;
+ }
+ }
+
+ void paintPoint(Canvas canvas, float x, float y) {
+ if (x == Float.NaN) {
+ return;
+ }
+
+ Paint paint = new Paint();
+
+ paint.setStyle(Paint.Style.FILL);
+ paint.setColor(Color.BLUE);
+ int[] colors3 = new int[] {
+ mSliderColor, mSliderColor, 0x66000000, 0 };
+ RadialGradient g = new RadialGradient(x, y, mCenterDotSize, colors3, new float[] {
+ 0, .3f, .31f, 1 }, Shader.TileMode.CLAMP);
+ paint.setShader(g);
+ canvas.drawCircle(x, y, mCenterDotSize, paint);
+ }
+
+ void paintRadius(Canvas canvas, float cx, float cy, float rx, float ry) {
+ if (cx == Float.NaN) {
+ return;
+ }
+ int mSliderColor = 0xFF33B5E5;
+ Paint paint = new Paint();
+ RectF rect = new RectF(cx - rx, cy - ry, cx + rx, cy + ry);
+ paint.setAntiAlias(true);
+ paint.setStyle(Paint.Style.STROKE);
+ paint.setStrokeWidth(6);
+ paint.setColor(Color.BLACK);
+ paintOvallines(canvas, rect, paint, cx, cy, rx, ry);
+
+ paint.setStrokeWidth(3);
+ paint.setColor(Color.WHITE);
+ paintOvallines(canvas, rect, paint, cx, cy, rx, ry);
+ }
+
+ public void paintOvallines(
+ Canvas canvas, RectF rect, Paint paint, float cx, float cy, float rx, float ry) {
+ canvas.drawOval(rect, paint);
+ float da = 4;
+ float arclen = da + da;
+ for (int i = 0; i < 361; i += 90) {
+ float dx = rx + 10;
+ float dy = ry + 10;
+ rect.left = cx - dx;
+ rect.top = cy - dy;
+ rect.right = cx + dx;
+ rect.bottom = cy + dy;
+ canvas.drawArc(rect, i - da, arclen, false, paint);
+ dx = rx - 10;
+ dy = ry - 10;
+ rect.left = cx - dx;
+ rect.top = cy - dy;
+ rect.right = cx + dx;
+ rect.bottom = cy + dy;
+ canvas.drawArc(rect, i - da, arclen, false, paint);
+ }
+ da *= 2;
+ for (int i = 45; i < 361; i += 90) {
+ double angle = Math.PI * i / 180.;
+ float x = cx + (float) (rx * Math.cos(angle));
+ float y = cy + (float) (ry * Math.sin(angle));
+ canvas.drawRect(x - da, y - da, x + da, y + da, paint);
+ }
+ rect.left = cx - rx;
+ rect.top = cy - ry;
+ rect.right = cx + rx;
+ rect.bottom = cy + ry;
+ }
+
+ public void fillHandles(Canvas canvas, float cx, float cy, float rx, float ry) {
+ handlex[0] = cx;
+ handley[0] = cy;
+ int k = 1;
+
+ for (int i = 0; i < 360; i += 45) {
+ double angle = Math.PI * i / 180.;
+
+ float x = cx + (float) (rx * Math.cos(angle));
+ float y = cy + (float) (ry * Math.sin(angle));
+ handlex[k] = x;
+ handley[k] = y;
+
+ k++;
+ }
+ }
+
+ public void draw(Canvas canvas) {
+ paintRadius(canvas, mCenterX, mCenterY, mRadiusX, mRadiusY);
+ fillHandles(canvas, mCenterX, mCenterY, mRadiusX, mRadiusY);
+ paintPoint(canvas, mCenterX, mCenterY);
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImagePoint.java b/src/com/android/gallery3d/filtershow/imageshow/ImagePoint.java
index 06b055d3c..625cdbe0d 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImagePoint.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImagePoint.java
@@ -75,13 +75,9 @@ public abstract class ImagePoint extends ImageShow {
paint.setColor(Color.RED);
paint.setStrokeWidth(2);
- GeometryMetadata geo = getImagePreset().mGeoData;
- Matrix originalToScreen = geo.getOriginalToScreen(false,
- mImageLoader.getOriginalBounds().width(),
- mImageLoader.getOriginalBounds().height(), getWidth(), getHeight());
- Matrix originalRotateToScreen = geo.getOriginalToScreen(true,
- mImageLoader.getOriginalBounds().width(),
- mImageLoader.getOriginalBounds().height(), getWidth(), getHeight());
+ Matrix originalToScreen = getImageToScreenMatrix(false);
+ Matrix originalRotateToScreen = getImageToScreenMatrix(true);
+
if (mRedEyeRep != null) {
for (FilterPoint candidate : mRedEyeRep.getCandidates()) {
drawPoint(candidate, canvas, originalToScreen, originalRotateToScreen, paint);
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageRedEye.java b/src/com/android/gallery3d/filtershow/imageshow/ImageRedEye.java
index c3ff5e151..9e667986e 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageRedEye.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageRedEye.java
@@ -62,16 +62,8 @@ public class ImageRedEye extends ImagePoint {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (mCurrentRect != null) {
// transform to original coordinates
- GeometryMetadata geo = getImagePreset().mGeoData;
- Matrix originalToScreen = geo.getOriginalToScreen(true,
- mImageLoader.getOriginalBounds().width(),
- mImageLoader.getOriginalBounds().height(),
- getWidth(), getHeight());
- Matrix originalNoRotateToScreen = geo.getOriginalToScreen(false,
- mImageLoader.getOriginalBounds().width(),
- mImageLoader.getOriginalBounds().height(),
- getWidth(), getHeight());
-
+ Matrix originalNoRotateToScreen = getImageToScreenMatrix(false);
+ Matrix originalToScreen = getImageToScreenMatrix(true);
Matrix invert = new Matrix();
originalToScreen.invert(invert);
RectF r = new RectF(mCurrentRect);
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java b/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java
index 463756839..94df06acb 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -269,6 +270,34 @@ public class ImageShow extends View implements OnGestureListener,
return GeometryMath.roundNearest(getImagePreset().mGeoData.getPreviewCropBounds());
}
+ /* consider moving the following 2 methods into a subclass */
+ /**
+ * This function calculates a Image to Screen Transformation matrix
+ *
+ * @param reflectRotation set true if you want the rotation encoded
+ * @return Image to Screen transformation matrix
+ */
+ protected Matrix getImageToScreenMatrix(boolean reflectRotation) {
+ GeometryMetadata geo = getImagePreset().mGeoData;
+ Matrix m = geo.getOriginalToScreen(reflectRotation,
+ mImageLoader.getOriginalBounds().width(),
+ mImageLoader.getOriginalBounds().height(), getWidth(), getHeight());
+ return m;
+ }
+
+ /**
+ * This function calculates a to Screen Image Transformation matrix
+ *
+ * @param reflectRotation set true if you want the rotation encoded
+ * @return Screen to Image transformation matrix
+ */
+ protected Matrix getScreenToImageMatrix(boolean reflectRotation) {
+ Matrix m = getImageToScreenMatrix(reflectRotation);
+ Matrix invert = new Matrix();
+ m.invert(invert);
+ return invert;
+ }
+
public Rect getDisplayedImageBounds() {
return mImageBounds;
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageTinyPlanet.java b/src/com/android/gallery3d/filtershow/imageshow/ImageTinyPlanet.java
index 3e95d4e15..3795d1f21 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageTinyPlanet.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageTinyPlanet.java
@@ -22,6 +22,7 @@ import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
+import com.android.gallery3d.filtershow.editors.BasicEditor;
import com.android.gallery3d.filtershow.editors.EditorTinyPlanet;
import com.android.gallery3d.filtershow.filters.FilterCurvesRepresentation;
import com.android.gallery3d.filtershow.filters.FilterTinyPlanetRepresentation;
@@ -37,7 +38,7 @@ public class ImageTinyPlanet extends ImageShow {
private float mCenterY = 0;
private float mStartAngle = 0;
private FilterTinyPlanetRepresentation mTinyPlanetRep;
- private EditorTinyPlanet mEditorTinyPlanet;
+ private BasicEditor mEditorTinyPlanet;
public ImageTinyPlanet(Context context) {
super(context);
@@ -94,7 +95,7 @@ public class ImageTinyPlanet extends ImageShow {
mTinyPlanetRep = tinyPlanetRep;
}
- public void setEditor(EditorTinyPlanet editorTinyPlanet) {
+ public void setEditor(BasicEditor editorTinyPlanet) {
mEditorTinyPlanet = editorTinyPlanet;
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageVignette.java b/src/com/android/gallery3d/filtershow/imageshow/ImageVignette.java
new file mode 100644
index 000000000..d56cc4713
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageVignette.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.filtershow.imageshow;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+import com.android.gallery3d.filtershow.editors.EditorVignette;
+import com.android.gallery3d.filtershow.filters.FilterVignetteRepresentation;
+
+public class ImageVignette extends ImageShow {
+ private static final String LOGTAG = "ImageVignette";
+
+ private FilterVignetteRepresentation mVignetteRep;
+ private EditorVignette mEditorVignette;
+
+ private int mActiveHandle = -1;
+
+ EclipseControl mElipse;
+
+ public ImageVignette(Context context) {
+ super(context);
+ mElipse = new EclipseControl(context);
+ }
+
+ public ImageVignette(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mElipse = new EclipseControl(context);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ int mask = event.getActionMasked();
+ if (MotionEvent.ACTION_UP == mask) {
+ mActiveHandle = -1;
+ }
+ if (MotionEvent.ACTION_DOWN == mask && event.getPointerCount() == 1) {
+ mActiveHandle = mElipse.getCloseHandle(event.getX(), event.getY());
+ }
+ if (mActiveHandle == -1 || event.getPointerCount() > 1) {
+ mActiveHandle = -1;
+
+ return super.onTouchEvent(event);
+ }
+ float x = event.getX();
+ float y = event.getY();
+
+ mElipse.setScrToImageMatrix(getScreenToImageMatrix(true));
+
+ switch (mask) {
+ case (MotionEvent.ACTION_DOWN):
+ mElipse.actionDown(x, y, mVignetteRep);
+ break;
+ case (MotionEvent.ACTION_UP):
+ case (MotionEvent.ACTION_MOVE):
+
+ mElipse.actionMove(mActiveHandle, x, y, mVignetteRep);
+ setRepresentation(mVignetteRep);
+ break;
+ }
+ resetImageCaches(this);
+ invalidate();
+ mEditorVignette.commitLocalRepresentation();
+ return true;
+ }
+
+ public void setRepresentation(FilterVignetteRepresentation vignetteRep) {
+ mVignetteRep = vignetteRep;
+ Matrix toImg = getScreenToImageMatrix(false);
+ Matrix toScr = new Matrix();
+ toImg.invert(toScr);
+
+ float[] c = new float[] {
+ mVignetteRep.getCenterX(), mVignetteRep.getCenterY() };
+ if (Float.isNaN(c[0])) {
+ float cx = mImageLoader.getOriginalBounds().width() / 2;
+ float cy = mImageLoader.getOriginalBounds().height() / 2;
+ float rx = cx * .8f;
+ float ry = cy * .8f;
+ mVignetteRep.setCenter(cx, cy);
+ mVignetteRep.setRadius(rx, ry);
+
+ c[0] = cx;
+ c[1] = cy;
+ toScr.mapPoints(c);
+
+ mElipse.setCenter(c[0], c[1]);
+ mElipse.setRadius(c[0] * 0.8f, c[1] * 0.8f);
+ } else {
+
+ toScr.mapPoints(c);
+
+ mElipse.setCenter(c[0], c[1]);
+ mElipse.setRadius(toScr.mapRadius(mVignetteRep.getRadiusX()),
+ toScr.mapRadius(mVignetteRep.getRadiusY()));
+ }
+ }
+
+ public void setEditor(EditorVignette editorVignette) {
+ mEditorVignette = editorVignette;
+ }
+
+ @Override
+ public void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ mElipse.draw(canvas);
+
+ }
+
+}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/Oval.java b/src/com/android/gallery3d/filtershow/imageshow/Oval.java
new file mode 100644
index 000000000..28f278f1c
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/imageshow/Oval.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.filtershow.imageshow;
+
+public interface Oval {
+ void setCenter(float x, float y);
+ void setRadius(float w, float h);
+ float getCenterX();
+ float getCenterY();
+ float getRadiusX();
+ float getRadiusY();
+ void setRadiusY(float y);
+ void setRadiusX(float x);
+
+}
diff --git a/src_pd/com/android/gallery3d/filtershow/editors/EditorManager.java b/src_pd/com/android/gallery3d/filtershow/editors/EditorManager.java
index 67ccf9c80..92962cbb1 100644
--- a/src_pd/com/android/gallery3d/filtershow/editors/EditorManager.java
+++ b/src_pd/com/android/gallery3d/filtershow/editors/EditorManager.java
@@ -28,6 +28,7 @@ public class EditorManager {
editorPlaceHolder.addEditor(new EditorCurves());
editorPlaceHolder.addEditor(new EditorTinyPlanet());
editorPlaceHolder.addEditor(new EditorDraw());
+ editorPlaceHolder.addEditor(new EditorVignette());
}
}