vignette fix & enhance to remove center focus
Change-Id: Ide19925c5a9113518815d3aacc2204ef5ab9661d
diff --git a/jni/Android.mk b/jni/Android.mk
index e612486..0b8480e 100644
--- a/jni/Android.mk
+++ b/jni/Android.mk
@@ -37,7 +37,6 @@
filters/vibrance.c \
filters/geometry.c \
filters/negative.c \
- filters/vignette.c \
filters/redEyeMath.c \
filters/fx.c \
filters/wbalance.c \
diff --git a/jni/filters/vignette.c b/jni/filters/vignette.c
deleted file mode 100644
index b9ee3ff..0000000
--- a/jni/filters/vignette.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.
- */
-
-#include "filters.h"
-#include <math.h>
-
-static int* gVignetteMap = 0;
-static int gVignetteWidth = 0;
-static int gVignetteHeight = 0;
-
-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);
- 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)
- {
- 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);
- }
- AndroidBitmap_unlockPixels(env, bitmap);
-}
diff --git a/res/layout-land/filtershow_vignette_controls.xml b/res/layout-land/filtershow_vignette_controls.xml
new file mode 100644
index 0000000..9bfb29f
--- /dev/null
+++ b/res/layout-land/filtershow_vignette_controls.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:fadeScrollbars="false">
+
+ <GridLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:alignmentMode="alignBounds"
+ android:useDefaultMargins="true"
+ android:columnOrderPreserved="false"
+ android:columnCount="2">
+
+ <TextView
+ android:layout_gravity="left|center_vertical"
+ android:text="@string/vignette_exposure"
+ android:textStyle="bold"
+ android:layout_marginLeft="8dp"
+ android:visibility="gone"/>
+ <TextView
+ android:layout_gravity="right|center_vertical"
+ android:id="@+id/exposureValue"
+ android:layout_marginRight="16dp"
+ android:visibility="gone"/>
+ <SeekBar
+ android:id="@+id/exposureSeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/FilterShowSlider"
+ android:layout_columnSpan="2"
+ android:visibility="gone"/>
+
+ <TextView
+ android:layout_gravity="left|center_vertical"
+ android:text="@string/vignette_saturation"
+ android:textStyle="bold"
+ android:layout_marginLeft="8dp"/>
+ <TextView
+ android:layout_gravity="right|center_vertical"
+ android:id="@+id/saturationValue"
+ android:layout_marginRight="16dp"/>
+ <SeekBar
+ android:id="@+id/saturationSeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/FilterShowSlider"
+ android:layout_columnSpan="2"/>
+
+ <TextView
+ android:layout_gravity="left|center_vertical"
+ android:text="@string/vignette_contrast"
+ android:textStyle="bold"
+ android:layout_marginLeft="8dp"/>
+ <TextView
+ android:layout_gravity="right|center_vertical"
+ android:id="@+id/contrastValue"
+ android:layout_marginRight="16dp"/>
+ <SeekBar
+ android:id="@+id/contrastSeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/FilterShowSlider"
+ android:layout_columnSpan="2"/>
+
+ <TextView
+ android:layout_gravity="left|center_vertical"
+ android:text="@string/vignette_falloff"
+ android:textStyle="bold"
+ android:layout_marginLeft="8dp"/>
+ <TextView
+ android:layout_gravity="right|center_vertical"
+ android:id="@+id/falloffValue"
+ android:layout_marginRight="16dp"/>
+ <SeekBar
+ android:id="@+id/falloffSeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/FilterShowSlider"
+ android:layout_columnSpan="2"/>
+
+ </GridLayout>
+ </ScrollView>
+
+ <GridLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="128dp"
+ android:alignmentMode="alignBounds"
+ android:useDefaultMargins="true"
+ android:columnOrderPreserved="false"
+ android:layout_weight="1"
+ android:columnCount="2">
+
+ <TextView
+ android:layout_gravity="left|center_vertical"
+ android:text="@string/vignette_main"
+ android:layout_marginLeft="8dp"/>
+ <TextView
+ android:layout_gravity="right|center_vertical"
+ android:id="@+id/mainVignetteValue"
+ android:layout_marginRight="16dp"/>
+ <SeekBar
+ android:id="@+id/mainVignetteSeekbar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/FilterShowSlider"
+ android:layout_columnSpan="2"/>
+ </GridLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/menu/filtershow_menu_vignette.xml b/res/menu/filtershow_menu_vignette.xml
new file mode 100644
index 0000000..2b32424
--- /dev/null
+++ b/res/menu/filtershow_menu_vignette.xml
@@ -0,0 +1,38 @@
+<!--
+ 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.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <group android:id="@+id/grunge_popupmenu" >
+ <item
+ android:id="@+id/editor_vignette_main"
+ android:title="@string/vignette_main"/>
+ <item
+ android:id="@+id/editor_vignette_falloff"
+ android:title="@string/vignette_falloff"/>
+ <item
+ android:id="@+id/editor_vignette_contrast"
+ android:title="@string/vignette_contrast"/>
+ <item
+ android:id="@+id/editor_vignette_saturation"
+ android:title="@string/vignette_saturation"/>
+ <item
+ android:id="@+id/editor_vignette_exposure"
+ android:title="@string/vignette_exposure"
+ android:visible= "false"/>
+ </group>
+
+</menu>
\ No newline at end of file
diff --git a/res/values/filtershow_strings.xml b/res/values/filtershow_strings.xml
index 4c8996a..802c8e0 100644
--- a/res/values/filtershow_strings.xml
+++ b/res/values/filtershow_strings.xml
@@ -154,6 +154,17 @@
<string name="curvesRGB">Curves</string>
<!-- Label for the image vignette filter (darkens photo around edges) button [CHAR LIMIT=10] -->
<string name="vignette">Vignette</string>
+ <!-- Label for the image vignette main parameter ui [CHAR LIMIT=15] -->
+ <string name="vignette_main">Vignette</string>
+ <!-- Label for the image vignette exposure parameter ui [CHAR LIMIT=15] -->
+ <string name="vignette_exposure">Exposure</string>
+ <!-- Label for the image vignette saturation parameter ui [CHAR LIMIT=15] -->
+ <string name="vignette_saturation">Saturation</string>
+ <!-- Label for the image vignette contrast fparameter ui [CHAR LIMIT=15] -->
+ <string name="vignette_contrast">Contrast</string>
+ <!-- Label for the image vignette Falloff rate parameter ui [CHAR LIMIT=15] -->
+ <string name="vignette_falloff">Falloff</string>
+
<!-- Label for the image effect that removes redeye. [CHAR LIMIT=10] -->
<string name="redeye">Red Eye</string>
<!-- Label for the that allows drawing on Image [CHAR LIMIT=10] -->
diff --git a/src/com/android/gallery3d/filtershow/editors/EditorVignette.java b/src/com/android/gallery3d/filtershow/editors/EditorVignette.java
index 7127b21..3a94dce 100644
--- a/src/com/android/gallery3d/filtershow/editors/EditorVignette.java
+++ b/src/com/android/gallery3d/filtershow/editors/EditorVignette.java
@@ -17,11 +17,22 @@
package com.android.gallery3d.filtershow.editors;
import android.content.Context;
+import android.os.Handler;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.PopupMenu;
+import android.widget.SeekBar;
+import android.widget.TextView;
import com.android.gallery3d.R;
-import com.android.gallery3d.filtershow.filters.FilterRepresentation;
+import com.android.gallery3d.filtershow.controller.BasicParameterInt;
+import com.android.gallery3d.filtershow.controller.Parameter;
import com.android.gallery3d.filtershow.filters.FilterVignetteRepresentation;
+import com.android.gallery3d.filtershow.filters.FilterRepresentation;
import com.android.gallery3d.filtershow.imageshow.ImageVignette;
public class EditorVignette extends ParametricEditor {
@@ -29,6 +40,33 @@
private static final String LOGTAG = "EditorVignettePlanet";
ImageVignette mImageVignette;
+ private SeekBar mVignetteBar;
+ private SeekBar mExposureBar;
+ private SeekBar mSaturationBar;
+ private SeekBar mContrastBar;
+ private SeekBar mFalloffBar;
+
+
+ private TextView mVignetteValue;
+ private TextView mExposureValue;
+ private TextView mSaturationValue;
+ private TextView mContrastValue;
+ private TextView mFalloffValue;
+
+ private SwapButton mButton;
+ private final Handler mHandler = new Handler();
+
+ int[] mMenuStrings = {
+ R.string.vignette_main,
+ R.string.vignette_exposure,
+ R.string.vignette_saturation,
+ R.string.vignette_contrast,
+ R.string.vignette_falloff,
+ };
+
+ String mCurrentlyEditing = null;
+
+
public EditorVignette() {
super(ID, R.layout.filtershow_vignette_editor, R.id.imageVignette);
}
@@ -42,12 +80,299 @@
@Override
public void reflectCurrentFilter() {
- super.reflectCurrentFilter();
+ if (useCompact(mContext)) {
+ super.reflectCurrentFilter();
- FilterRepresentation rep = getLocalRepresentation();
- if (rep != null && getLocalRepresentation() instanceof FilterVignetteRepresentation) {
- FilterVignetteRepresentation drawRep = (FilterVignetteRepresentation) rep;
- mImageVignette.setRepresentation(drawRep);
+ FilterRepresentation rep = getLocalRepresentation();
+ if (rep != null && getLocalRepresentation() instanceof FilterVignetteRepresentation) {
+ FilterVignetteRepresentation drawRep = (FilterVignetteRepresentation) rep;
+ mImageVignette.setRepresentation(drawRep);
+ }
+ updateText();
+ return;
}
+ mLocalRepresentation = null;
+ if (getLocalRepresentation() != null
+ && getLocalRepresentation() instanceof FilterVignetteRepresentation) {
+ FilterVignetteRepresentation rep =
+ (FilterVignetteRepresentation) getLocalRepresentation();
+ int min;
+ int []mode = {
+ FilterVignetteRepresentation.MODE_VIGNETTE,
+ FilterVignetteRepresentation.MODE_EXPOSURE,
+ FilterVignetteRepresentation.MODE_SATURATION,
+ FilterVignetteRepresentation.MODE_CONTRAST,
+ FilterVignetteRepresentation.MODE_FALLOFF
+ };
+ SeekBar []sliders = {
+ mVignetteBar,
+ mExposureBar,
+ mSaturationBar,
+ mContrastBar,
+ mFalloffBar
+ };
+ TextView []label = {
+ mVignetteValue,
+ mExposureValue,
+ mSaturationValue,
+ mContrastValue,
+ mFalloffValue
+ };
+ for (int i = 0; i < mode.length; i++) {
+ BasicParameterInt p = (BasicParameterInt) rep.getFilterParameter(mode[i]);
+ int value = p.getValue();
+ sliders[i].setMax(p.getMaximum() - p.getMinimum());
+ sliders[i].setProgress(value - p.getMinimum());
+ label[i].setText("" + value);
+ }
+
+ mImageVignette.setRepresentation(rep);
+ String text = mContext.getString(rep.getTextId()).toUpperCase();
+ mFilterTitle.setText(text);
+ updateText();
+ }
+ }
+
+
+
+ @Override
+ public String calculateUserMessage(Context context, String effectName, Object parameterValue) {
+ FilterRepresentation rep = getLocalRepresentation();
+ if (rep == null || !(rep instanceof FilterVignetteRepresentation)) {
+ return "";
+ }
+ FilterVignetteRepresentation csrep = (FilterVignetteRepresentation) rep;
+ int mode = csrep.getParameterMode();
+ String paramString;
+
+ paramString = mContext.getString(mMenuStrings[mode]);
+
+ int val = csrep.getCurrentParameter();
+ return paramString + ((val > 0) ? " +" : " ") + val;
+ }
+
+ @Override
+ public void openUtilityPanel(final LinearLayout accessoryViewList) {
+ mButton = (SwapButton) accessoryViewList.findViewById(R.id.applyEffect);
+ mButton.setText(mContext.getString(R.string.vignette_main));
+
+ if (useCompact(mContext)) {
+ final PopupMenu popupMenu = new PopupMenu(mImageShow.getActivity(), mButton);
+
+ popupMenu.getMenuInflater().inflate(R.menu.filtershow_menu_vignette,
+ popupMenu.getMenu());
+
+ popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ selectMenuItem(item);
+ return true;
+ }
+ });
+ mButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ popupMenu.show();
+ }
+ });
+ mButton.setListener(this);
+
+ FilterVignetteRepresentation csrep = getVignetteRep();
+ String menuString = mContext.getString(mMenuStrings[0]);
+ switchToMode(csrep, FilterVignetteRepresentation.MODE_VIGNETTE, menuString);
+ } else {
+ mButton.setText(mContext.getString(R.string.vignette_main));
+ }
+ }
+
+ @Override
+ public void setUtilityPanelUI(View actionButton, View editControl) {
+ if (useCompact(mContext)) {
+ super.setUtilityPanelUI(actionButton, editControl);
+ return;
+ }
+ mActionButton = actionButton;
+ mEditControl = editControl;
+ mEditTitle.setCompoundDrawables(null, null, null, null);
+ LinearLayout group = (LinearLayout) editControl;
+ LayoutInflater inflater =
+ (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ LinearLayout controls = (LinearLayout) inflater.inflate(
+ R.layout.filtershow_vignette_controls, group, false);
+ ViewGroup.LayoutParams lp = new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+ controls.setLayoutParams(lp);
+ group.removeAllViews();
+ group.addView(controls);
+
+ mVignetteBar = (SeekBar) controls.findViewById(R.id.mainVignetteSeekbar);
+ mVignetteBar.setMax(200);
+ mVignetteBar.setOnSeekBarChangeListener(this);
+ mVignetteValue = (TextView) controls.findViewById(R.id.mainVignetteValue);
+ mExposureBar = (SeekBar) controls.findViewById(R.id.exposureSeekBar);
+ mExposureBar.setMax(200);
+ mExposureBar.setOnSeekBarChangeListener(this);
+ mExposureValue = (TextView) controls.findViewById(R.id.exposureValue);
+ mSaturationBar = (SeekBar) controls.findViewById(R.id.saturationSeekBar);
+ mSaturationBar.setMax(200);
+ mSaturationBar.setOnSeekBarChangeListener(this);
+ mSaturationValue = (TextView) controls.findViewById(R.id.saturationValue);
+ mContrastBar = (SeekBar) controls.findViewById(R.id.contrastSeekBar);
+ mContrastBar.setMax(200);
+ mContrastBar.setOnSeekBarChangeListener(this);
+ mContrastValue = (TextView) controls.findViewById(R.id.contrastValue);
+ mFalloffBar = (SeekBar) controls.findViewById(R.id.falloffSeekBar);
+ mFalloffBar.setMax(200);
+ mFalloffBar.setOnSeekBarChangeListener(this);
+ mFalloffValue = (TextView) controls.findViewById(R.id.falloffValue);
+ }
+
+ public int getParameterIndex(int id) {
+ switch (id) {
+ case R.id.editor_vignette_main:
+ return FilterVignetteRepresentation.MODE_VIGNETTE;
+ case R.id.editor_vignette_saturation:
+ return FilterVignetteRepresentation.MODE_SATURATION;
+ case R.id.editor_vignette_contrast:
+ return FilterVignetteRepresentation.MODE_CONTRAST;
+ case R.id.editor_vignette_exposure:
+ return FilterVignetteRepresentation.MODE_EXPOSURE;
+ case R.id.editor_vignette_falloff:
+ return FilterVignetteRepresentation.MODE_FALLOFF;
+ }
+ return -1;
+ }
+
+ @Override
+ public void detach() {
+ if (mButton == null) {
+ return;
+ }
+ mButton.setListener(null);
+ mButton.setOnClickListener(null);
+ }
+
+ private void updateSeekBar(FilterVignetteRepresentation rep) {
+ mControl.updateUI();
+ }
+
+ @Override
+ protected Parameter getParameterToEdit(FilterRepresentation rep) {
+ if (rep instanceof FilterVignetteRepresentation) {
+ FilterVignetteRepresentation csrep = (FilterVignetteRepresentation) rep;
+ Parameter param = csrep.getFilterParameter(csrep.getParameterMode());
+
+ return param;
+ }
+ return null;
+ }
+
+ private FilterVignetteRepresentation getVignetteRep() {
+ FilterRepresentation rep = getLocalRepresentation();
+ if (rep != null
+ && rep instanceof FilterVignetteRepresentation) {
+ FilterVignetteRepresentation csrep = (FilterVignetteRepresentation) rep;
+ return csrep;
+ }
+ return null;
+ }
+
+ protected void selectMenuItem(MenuItem item) {
+ if (getLocalRepresentation() != null
+ && getLocalRepresentation() instanceof FilterVignetteRepresentation) {
+ FilterVignetteRepresentation csrep =
+ (FilterVignetteRepresentation) getLocalRepresentation();
+
+ switchToMode(csrep, getParameterIndex(item.getItemId()), item.getTitle().toString());
+ }
+ }
+
+ protected void switchToMode(FilterVignetteRepresentation csrep, int mode, String title) {
+ if (csrep == null) {
+ return;
+ }
+ csrep.setParameterMode(mode);
+ mCurrentlyEditing = title;
+ mButton.setText(mCurrentlyEditing);
+ {
+ Parameter param = getParameterToEdit(csrep);
+
+ control(param, mEditControl);
+ }
+ updateSeekBar(csrep);
+ mView.invalidate();
+ }
+
+ @Override
+ public void onProgressChanged(SeekBar sbar, int progress, boolean arg2) {
+ FilterVignetteRepresentation rep = getVignetteRep();
+ int value = progress;
+ BasicParameterInt p;
+ switch (sbar.getId()) {
+ case R.id.mainVignetteSeekbar:
+ rep.setParameterMode(FilterVignetteRepresentation.MODE_VIGNETTE);
+ p = rep.getFilterParameter(rep.getParameterMode());
+ value += p.getMinimum();
+ mVignetteValue.setText("" + value);
+ break;
+ case R.id.exposureSeekBar:
+ rep.setParameterMode(FilterVignetteRepresentation.MODE_EXPOSURE);
+ p = rep.getFilterParameter(rep.getParameterMode());
+ value += p.getMinimum();
+ mExposureValue.setText("" + value);
+ break;
+ case R.id.saturationSeekBar:
+ rep.setParameterMode(FilterVignetteRepresentation.MODE_SATURATION);
+ p = rep.getFilterParameter(rep.getParameterMode());
+ value += p.getMinimum();
+ mSaturationValue.setText("" + value);
+ break;
+ case R.id.contrastSeekBar:
+ rep.setParameterMode(FilterVignetteRepresentation.MODE_CONTRAST);
+ p = rep.getFilterParameter(rep.getParameterMode());
+ value += p.getMinimum();
+ mContrastValue.setText("" + value);
+ break;
+ case R.id.falloffSeekBar:
+ rep.setParameterMode(FilterVignetteRepresentation.MODE_FALLOFF);
+ p = rep.getFilterParameter(rep.getParameterMode());
+ value += p.getMinimum();
+ mFalloffValue.setText("" + value);
+ break;
+ }
+ rep.setCurrentParameter(value);
+ commitLocalRepresentation();
+ }
+
+ @Override
+ public void swapLeft(MenuItem item) {
+ super.swapLeft(item);
+ mButton.setTranslationX(0);
+ mButton.animate().translationX(mButton.getWidth()).setDuration(SwapButton.ANIM_DURATION);
+ Runnable updateButton = new Runnable() {
+ @Override
+ public void run() {
+ mButton.animate().cancel();
+ mButton.setTranslationX(0);
+ }
+ };
+ mHandler.postDelayed(updateButton, SwapButton.ANIM_DURATION);
+ selectMenuItem(item);
+ }
+
+ @Override
+ public void swapRight(MenuItem item) {
+ super.swapRight(item);
+ mButton.setTranslationX(0);
+ mButton.animate().translationX(-mButton.getWidth()).setDuration(SwapButton.ANIM_DURATION);
+ Runnable updateButton = new Runnable() {
+ @Override
+ public void run() {
+ mButton.animate().cancel();
+ mButton.setTranslationX(0);
+ }
+ };
+ mHandler.postDelayed(updateButton, SwapButton.ANIM_DURATION);
+ selectMenuItem(item);
}
}
diff --git a/src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java
index 8429d3b..2e362f8 100644
--- a/src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java
+++ b/src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java
@@ -16,19 +16,48 @@
package com.android.gallery3d.filtershow.filters;
+import android.util.JsonReader;
+import android.util.JsonWriter;
+
import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.controller.BasicParameterInt;
+import com.android.gallery3d.filtershow.controller.Parameter;
import com.android.gallery3d.filtershow.editors.EditorVignette;
import com.android.gallery3d.filtershow.imageshow.Oval;
-public class FilterVignetteRepresentation extends FilterBasicRepresentation implements Oval {
+import java.io.IOException;
+
+public class FilterVignetteRepresentation extends FilterRepresentation implements Oval {
private static final String LOGTAG = "FilterVignetteRepresentation";
- private float mCenterX = Float.NaN;
- private float mCenterY;
- private float mRadiusX = Float.NaN;
- private float mRadiusY;
+
+ private float mCenterX = .5f;
+ private float mCenterY = .5f;
+ private float mRadiusX = .5f;
+ private float mRadiusY = .5f;
+ public static final int MODE_VIGNETTE = 0;
+ public static final int MODE_EXPOSURE = 1;
+ public static final int MODE_SATURATION = 2;
+ public static final int MODE_CONTRAST = 3;
+ public static final int MODE_FALLOFF = 4;
+ private static int MIN = -100;
+ private static int MAX = 100;
+ private static int MAXFALLOF = 200;
+
+ private BasicParameterInt mParamVignette = new BasicParameterInt(MODE_VIGNETTE, 0, MIN, MAX);
+ private BasicParameterInt mParamExposure = new BasicParameterInt(MODE_EXPOSURE, 0, MIN, MAX);
+ private BasicParameterInt mParamSaturation = new BasicParameterInt(MODE_SATURATION, 0, MIN, MAX);
+ private BasicParameterInt mParamContrast = new BasicParameterInt(MODE_CONTRAST, 0, MIN, MAX);
+ private BasicParameterInt mParamFalloff = new BasicParameterInt(MODE_FALLOFF, 40, 0, MAXFALLOF);
+ private BasicParameterInt[] mAllParam = {
+ mParamVignette,
+ mParamExposure,
+ mParamSaturation,
+ mParamContrast,
+ mParamFalloff};
+ private int mParameterMode;
public FilterVignetteRepresentation() {
- super("Vignette", -100, 50, 100);
+ super("Vignette");
setSerializationName("VIGNETTE");
setShowParameterValue(true);
setFilterType(FilterRepresentation.TYPE_VIGNETTE);
@@ -36,18 +65,29 @@
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;
+ FilterVignetteRepresentation rep = (FilterVignetteRepresentation) a;
+ mCenterX = rep.mCenterX;
+ mCenterY = rep.mCenterY;
+ mRadiusX = rep.mRadiusX;
+ mRadiusY = rep.mRadiusY;
+ mParamVignette.setValue(rep.mParamVignette.getValue());
+ mParamExposure.setValue(rep.mParamExposure.getValue());
+ mParamSaturation.setValue(rep.mParamSaturation.getValue());
+ mParamContrast.setValue(rep.mParamContrast.getValue());
+ mParamFalloff.setValue(rep.mParamFalloff.getValue());
+ }
+
+ public int getValue(int mode) {
+ return mAllParam[mode].getValue();
+ }
+
+ public void setValue(int mode, int value) {
+ mAllParam[mode].setValue(value);
}
@Override
@@ -116,7 +156,7 @@
@Override
public boolean isNil() {
- return getValue() == 0;
+ return false;
}
@Override
@@ -126,6 +166,10 @@
}
if (representation instanceof FilterVignetteRepresentation) {
FilterVignetteRepresentation rep = (FilterVignetteRepresentation) representation;
+ for (int i = 0; i < mAllParam.length; i++) {
+ if (mAllParam[i].getValue() != rep.mAllParam[i].getValue())
+ return false;
+ }
if (rep.getCenterX() == getCenterX()
&& rep.getCenterY() == getCenterY()
&& rep.getRadiusX() == getRadiusX()
@@ -136,43 +180,87 @@
return false;
}
- private static final String[] sParams = {
- "Name", "value", "mCenterX", "mCenterY", "mRadiusX",
- "mRadiusY"
- };
-
+ private static final String ELLIPSE = "ellipse";
+ private static final String ARGS = "adjust";
@Override
- public String[][] serializeRepresentation() {
- String[][] ret = {
- { sParams[0], getName() },
- { sParams[1], Integer.toString(getValue()) },
- { sParams[2], Float.toString(mCenterX) },
- { sParams[3], Float.toString(mCenterY) },
- { sParams[4], Float.toString(mRadiusX) },
- { sParams[5], Float.toString(mRadiusY) }
- };
- return ret;
+ public void serializeRepresentation(JsonWriter writer) throws IOException {
+ writer.beginObject();
+ writer.name(ELLIPSE);
+ writer.beginArray();
+ writer.value(mCenterX);
+ writer.value(mCenterY);
+ writer.value(mRadiusX);
+ writer.value(mRadiusY);
+ writer.endArray();
+
+ writer.name(ARGS);
+ writer.beginArray();
+ writer.value(mParamVignette.getValue());
+ writer.value(mParamExposure.getValue());
+ writer.value(mParamSaturation.getValue());
+ writer.value(mParamContrast.getValue());
+ writer.value(mParamFalloff.getValue());
+ writer.endArray();
+ writer.endObject();
}
+
@Override
- public void deSerializeRepresentation(String[][] rep) {
- super.deSerializeRepresentation(rep);
- for (int i = 0; i < rep.length; i++) {
- String key = rep[i][0];
- String value = rep[i][1];
- if (sParams[0].equals(key)) {
- setName(value);
- } else if (sParams[1].equals(key)) {
- setValue(Integer.parseInt(value));
- } else if (sParams[2].equals(key)) {
- mCenterX = Float.parseFloat(value);
- } else if (sParams[3].equals(key)) {
- mCenterY = Float.parseFloat(value);
- } else if (sParams[4].equals(key)) {
- mRadiusX = Float.parseFloat(value);
- } else if (sParams[5].equals(key)) {
- mRadiusY = Float.parseFloat(value);
+ public void deSerializeRepresentation(JsonReader sreader) throws IOException {
+ sreader.beginObject();
+
+ while (sreader.hasNext()) {
+ String name = sreader.nextName();
+ if (name.startsWith(ELLIPSE)) {
+ sreader.beginArray();
+ sreader.hasNext();
+ mCenterX = (float) sreader.nextDouble();
+ sreader.hasNext();
+ mCenterY = (float) sreader.nextDouble();
+ sreader.hasNext();
+ mRadiusX = (float) sreader.nextDouble();
+ sreader.hasNext();
+ mRadiusY = (float) sreader.nextDouble();
+ sreader.hasNext();
+ sreader.endArray();
+ } else if (name.startsWith(ARGS)) {
+ sreader.beginArray();
+ sreader.hasNext();
+ mParamVignette.setValue(sreader.nextInt());
+ sreader.hasNext();
+ mParamExposure.setValue(sreader.nextInt());
+ sreader.hasNext();
+ mParamSaturation.setValue(sreader.nextInt());
+ sreader.hasNext();
+ mParamContrast.setValue(sreader.nextInt());
+ sreader.hasNext();
+ mParamFalloff.setValue(sreader.nextInt());
+ sreader.hasNext();
+ sreader.endArray();
+ } else {
+ sreader.skipValue();
}
}
+ sreader.endObject();
}
+ public int getParameterMode() {
+ return mParameterMode;
+ }
+
+ public void setParameterMode(int parameterMode) {
+ mParameterMode = parameterMode;
+ }
+
+ public int getCurrentParameter() {
+ return getValue(mParameterMode);
+ }
+
+ public void setCurrentParameter(int value) {
+ setValue(mParameterMode, value);
+ }
+
+ public BasicParameterInt getFilterParameter(int index) {
+ return mAllParam[index];
+ }
+
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java
index 7e0a452..0ab5016 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java
@@ -19,14 +19,26 @@
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
-import android.graphics.Matrix;
import android.graphics.Rect;
import com.android.gallery3d.R;
import com.android.gallery3d.filtershow.pipeline.FilterEnvironment;
+import android.support.v8.renderscript.Allocation;
+import android.support.v8.renderscript.Element;
+import android.support.v8.renderscript.RenderScript;
+import android.support.v8.renderscript.Script.LaunchOptions;
+import android.support.v8.renderscript.Type;
+import android.util.Log;
-public class ImageFilterVignette extends SimpleImageFilter {
+public class ImageFilterVignette extends ImageFilterRS {
private static final String LOGTAG = "ImageFilterVignette";
private Bitmap mOverlayBitmap;
+ private ScriptC_vignette mScript;
+ FilterVignetteRepresentation mParameters;
+ public static final int MODE_VIGNETTE = FilterVignetteRepresentation.MODE_VIGNETTE;
+ public static final int MODE_EXPOSURE = FilterVignetteRepresentation.MODE_EXPOSURE;
+ public static final int MODE_SATURATION = FilterVignetteRepresentation.MODE_SATURATION;
+ public static final int MODE_CONTRAST = FilterVignetteRepresentation.MODE_CONTRAST;
+ public static final int MODE_FALLOFF = FilterVignetteRepresentation.MODE_FALLOFF;
public ImageFilterVignette() {
mName = "Vignette";
@@ -38,8 +50,14 @@
return representation;
}
+ @Override
+ public void useRepresentation(FilterRepresentation representation) {
+ mParameters = (FilterVignetteRepresentation) representation;
+ }
+
native protected void nativeApplyFilter(
- Bitmap bitmap, int w, int h, int cx, int cy, float radx, float rady, float strength);
+ Bitmap bitmap, int w, int h, int cx, int cy, float radx, float rady,
+ float strength, float finalValue);
private float calcRadius(float cx, float cy, int w, int h) {
float d = cx;
@@ -56,6 +74,51 @@
}
@Override
+ protected void createFilter(Resources res, float scaleFactor, int quality) {
+ RenderScript rsCtx = getRenderScriptContext();
+
+ mScript = new ScriptC_vignette(rsCtx, res, R.raw.vignette);
+ }
+
+ @Override
+ protected void runFilter() {
+
+ int w = getInPixelsAllocation().getType().getX();
+ int h = getInPixelsAllocation().getType().getY();
+
+ float cx = w / 2;
+ float cy = h / 2;
+ float r = calcRadius(cx, cy, w, h);
+ float rx = r;
+ float ry = r;
+ if (mParameters.isCenterSet()) {
+
+ cx = mParameters.getCenterX() * w;
+ cy = mParameters.getCenterY() * h;
+
+ rx = mParameters.getRadiusX() * w;
+ ry = mParameters.getRadiusY() * h;
+ }
+
+
+ mScript.set_inputWidth(w);
+ mScript.set_inputHeight(h);
+ int v = mParameters.getValue(MODE_VIGNETTE);
+ mScript.set_finalSubtract((v < 0) ? v : 0);
+ mScript.set_finalBright((v > 0) ? -v : 0);
+ mScript.set_finalSaturation(mParameters.getValue(MODE_SATURATION));
+ mScript.set_finalContrast(mParameters.getValue(MODE_CONTRAST));
+ mScript.set_centerx(cx);
+ mScript.set_centery(cy);
+ mScript.set_radiusx(rx);
+ mScript.set_radiusy(ry);
+ mScript.set_strength(mParameters.getValue(MODE_FALLOFF)/10.f);
+ mScript.invoke_setupVignetteParams();
+ mScript.forEach_vignette(getInPixelsAllocation(), getOutPixelsAllocation());
+
+ }
+
+ @Override
public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
if (SIMPLE_ICONS && FilterEnvironment.QUALITY_ICON == quality) {
if (mOverlayBitmap == null) {
@@ -63,36 +126,33 @@
mOverlayBitmap = IconUtilities.getFXBitmap(res,
R.drawable.filtershow_icon_vignette);
}
+
Canvas c = new Canvas(bitmap);
int dim = Math.max(bitmap.getWidth(), bitmap.getHeight());
Rect r = new Rect(0, 0, dim, dim);
c.drawBitmap(mOverlayBitmap, null, r, null);
return bitmap;
}
- FilterVignetteRepresentation rep = (FilterVignetteRepresentation) getParameters();
- if (rep == null) {
- return bitmap;
- }
- int w = bitmap.getWidth();
- int h = bitmap.getHeight();
- 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);
+ Bitmap ret = super.apply(bitmap, scaleFactor, quality);
return bitmap;
}
+
+
+ @Override
+ protected void resetAllocations() {
+
+ }
+
+ @Override
+ public void resetScripts() {
+
+ }
+
+ @Override
+ protected void bindScriptValues() {
+ int width = getInPixelsAllocation().getType().getX();
+ int height = getInPixelsAllocation().getType().getY();
+ mScript.set_inputWidth(width);
+ mScript.set_inputHeight(height);
+ }
}
diff --git a/src/com/android/gallery3d/filtershow/filters/vignette.rs b/src/com/android/gallery3d/filtershow/filters/vignette.rs
new file mode 100644
index 0000000..709b220
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/filters/vignette.rs
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2013 Unknown
+ *
+ * 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.gallery3d.filtershow.filters)
+
+uint32_t inputWidth;
+uint32_t inputHeight;
+float centerx;
+float centery;
+float radiusx;
+float radiusy;
+float strength;
+float finalBright;
+float finalSaturation;
+float finalContrast;
+float finalSubtract;
+rs_matrix3x3 colorMatrix;
+float scalex;
+float scaley;
+float offset;
+static const float Rf = 0.2999f;
+static const float Gf = 0.587f;
+static const float Bf = 0.114f;
+
+
+void setupVignetteParams() {
+ int k = 0;
+
+ scalex = 1.f / radiusx;
+ scaley = 1.f / radiusy;
+
+ float S = 1 + finalSaturation / 100.f;
+ float MS = 1 - S;
+ float Rt = Rf * MS;
+ float Gt = Gf * MS;
+ float Bt = Bf * MS;
+
+ float b = 1 + finalBright / 100.f;
+ float c = 1 + finalContrast / 100.f;
+ b *= c;
+ offset = .5f - c / 2.f - finalSubtract / 100.f;
+ rsMatrixSet(&colorMatrix, 0, 0, b * (Rt + S));
+ rsMatrixSet(&colorMatrix, 1, 0, b * Gt);
+ rsMatrixSet(&colorMatrix, 2, 0, b * Bt);
+ rsMatrixSet(&colorMatrix, 0, 1, b * Rt);
+ rsMatrixSet(&colorMatrix, 1, 1, b * (Gt + S));
+ rsMatrixSet(&colorMatrix, 2, 1, b * Bt);
+ rsMatrixSet(&colorMatrix, 0, 2, b * Rt);
+ rsMatrixSet(&colorMatrix, 1, 2, b * Gt);
+ rsMatrixSet(&colorMatrix, 2, 2, b * (Bt + S));
+}
+
+uchar4 __attribute__((kernel)) vignette(const uchar4 in, uint32_t x, uint32_t y) {
+ float4 pixel = rsUnpackColor8888(in);
+ float radx = (x - centerx) * scalex;
+ float rady = (y - centery) * scaley;
+ float dist = strength * (sqrt(radx * radx + rady * rady) - 1.f);
+ float t = (1.f + dist / sqrt(1.f + dist* dist)) * .5f;
+ float4 wsum = pixel;
+ wsum.xyz = wsum.xyz * (1 - t) + t * (rsMatrixMultiply(&colorMatrix, wsum.xyz) + offset);
+ wsum.a = 1.0f;
+ uchar4 out = rsPackColorTo8888(clamp(wsum, 0.f, 1.0f));
+ return out;
+}
\ No newline at end of file
diff --git a/src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java b/src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java
index 068464c..4c0c24d 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java
@@ -25,6 +25,7 @@
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
+import android.util.Log;
import com.android.gallery3d.R;
@@ -34,7 +35,7 @@
private float mRadiusX = 200;
private float mRadiusY = 300;
private static int MIN_TOUCH_DIST = 80;// should be a resource & in dips
-
+ private static String LOGTAG = "EclipseControl";
private float[] handlex = new float[9];
private float[] handley = new float[9];
private int mSliderColor;
@@ -104,28 +105,39 @@
}
private boolean centerIsOutside(float x1, float y1) {
- return (!mImageBounds.contains((int) x1, (int) y1));
+ return (!mImageBounds.contains((int) x1, (int) y1));
}
- public void actionDown(float x, float y, Oval oval) {
- float[] point = new float[] {
- x, y };
+ public void actionDown2(float x, float y, int iw, int ih, 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();
+ mDownCenterX = oval.getCenterX() * iw;
+ mDownCenterY = oval.getCenterY() * ih;
+ mDownRadiusX = oval.getRadiusX() * iw;
+ mDownRadiusY = oval.getRadiusY() * ih;
+ }
+
+ public void actionDown(float x, float y, Oval oval) {
+ actionDown2(x, y, 1, 1, oval);
}
public void actionMove(int handle, float x, float y, Oval oval) {
- float[] point = new float[] {
- x, y };
+ actionMove2(handle, x, y, 1, 1, oval);
+ }
+
+ public void actionMove2(int handle, float x, float y, int w, int h, Oval oval) {
+ float[] point = new float[]{
+ x, y};
mScrToImg.mapPoints(point);
x = point[0];
y = point[1];
-
+ if (w == 0) {
+ w = 1;
+ h = 1;
+ }
// Test if the matrix is swapping x and y
point[0] = 0;
point[1] = 1;
@@ -140,7 +152,7 @@
if (centerIsOutside(x - ctrdx, y - ctrdy)) {
break;
}
- oval.setCenter(x - ctrdx, y - ctrdy);
+ oval.setCenter((x - ctrdx) / w, (y - ctrdy) / h);
// setRepresentation(mVignetteRep);
break;
case HAN_NORTH:
@@ -148,10 +160,10 @@
case HAN_SOUTH:
if (swapxy) {
float raddx = mDownRadiusY - Math.abs(mDownX - mDownCenterY);
- oval.setRadiusY(Math.abs(x - oval.getCenterY() + sign * raddx));
+ oval.setRadiusY(Math.abs(x - oval.getCenterY() * h + sign * raddx)/h);
} else {
float raddy = mDownRadiusY - Math.abs(mDownY - mDownCenterY);
- oval.setRadiusY(Math.abs(y - oval.getCenterY() + sign * raddy));
+ oval.setRadiusY(Math.abs(y - oval.getCenterY() * h + sign * raddy)/h);
}
break;
case HAN_EAST:
@@ -159,10 +171,10 @@
case HAN_WEST:
if (swapxy) {
float raddy = mDownRadiusX - Math.abs(mDownY - mDownCenterX);
- oval.setRadiusX(Math.abs(y - oval.getCenterX() + sign * raddy));
+ oval.setRadiusX(Math.abs(y - oval.getCenterX() * w + sign * raddy)/w);
} else {
float raddx = mDownRadiusX - Math.abs(mDownX - mDownCenterX);
- oval.setRadiusX(Math.abs(x - oval.getCenterX() - sign * raddx));
+ oval.setRadiusX(Math.abs(x - oval.getCenterX() * w - sign * raddx)/w);
}
break;
case HAN_SE:
@@ -174,13 +186,13 @@
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 rx = oval.getRadiusX() * w;
+ float ry = oval.getRadiusY() * h;
float r = (Math.abs(rx) + Math.abs(ry)) * sin45;
- float dx = x - oval.getCenterX();
- float dy = y - oval.getCenterY();
+ float dx = x - oval.getCenterX() * w;
+ float dy = y - oval.getCenterY() * h;
float nr = Math.abs(Math.abs(dx) + Math.abs(dy) - downRad);
- oval.setRadius(rx * nr / r, ry * nr / r);
+ oval.setRadius((rx * nr / r) / w, (ry * nr / r) / h);
break;
}
@@ -195,10 +207,10 @@
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.BLUE);
- int[] colors3 = new int[] {
- Color.GRAY, Color.LTGRAY, 0x66000000, 0 };
- RadialGradient g = new RadialGradient(x, y, mCenterDotSize, colors3, new float[] {
- 0, .3f, .31f, 1 }, Shader.TileMode.CLAMP);
+ int[] colors3 = new int[]{
+ Color.GRAY, Color.LTGRAY, 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);
}
@@ -212,10 +224,10 @@
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);
+ 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);
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageVignette.java b/src/com/android/gallery3d/filtershow/imageshow/ImageVignette.java
index 039aea9..389fe3f 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageVignette.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageVignette.java
@@ -48,6 +48,8 @@
@Override
public boolean onTouchEvent(MotionEvent event) {
+ int w = MasterImage.getImage().getOriginalBounds().width();
+ int h = MasterImage.getImage().getOriginalBounds().height();
int mask = event.getActionMasked();
if (mActiveHandle == -1) {
if (MotionEvent.ACTION_DOWN != mask) {
@@ -77,11 +79,11 @@
boolean didComputeEllipses = false;
switch (mask) {
case (MotionEvent.ACTION_DOWN):
- mElipse.actionDown(x, y, mVignetteRep);
+ mElipse.actionDown2(x, y, w, h, mVignetteRep);
break;
case (MotionEvent.ACTION_UP):
case (MotionEvent.ACTION_MOVE):
- mElipse.actionMove(mActiveHandle, x, y, mVignetteRep);
+ mElipse.actionMove2(mActiveHandle, x, y, w, h, mVignetteRep);
setRepresentation(mVignetteRep);
didComputeEllipses = true;
break;
@@ -102,19 +104,21 @@
if (mVignetteRep == null) {
return;
}
+ float w = MasterImage.getImage().getOriginalBounds().width();
+ float h = MasterImage.getImage().getOriginalBounds().height();
Matrix toImg = getScreenToImageMatrix(false);
Matrix toScr = new Matrix();
toImg.invert(toScr);
float[] c = new float[] {
- mVignetteRep.getCenterX(), mVignetteRep.getCenterY() };
+ mVignetteRep.getCenterX() * w, mVignetteRep.getCenterY() * h};
if (Float.isNaN(c[0])) {
- float cx = MasterImage.getImage().getOriginalBounds().width() / 2;
- float cy = MasterImage.getImage().getOriginalBounds().height() / 2;
+ float cx = w / 2;
+ float cy = h / 2;
float rx = Math.min(cx, cy) * .8f;
float ry = rx;
- mVignetteRep.setCenter(cx, cy);
- mVignetteRep.setRadius(rx, ry);
+ mVignetteRep.setCenter(cx / w, cy / h);
+ mVignetteRep.setRadius(rx / w, ry / h);
c[0] = cx;
c[1] = cy;
@@ -128,8 +132,8 @@
toScr.mapPoints(c);
mElipse.setCenter(c[0], c[1]);
- mElipse.setRadius(toScr.mapRadius(mVignetteRep.getRadiusX()),
- toScr.mapRadius(mVignetteRep.getRadiusY()));
+ mElipse.setRadius(toScr.mapRadius(mVignetteRep.getRadiusX() * w),
+ toScr.mapRadius(mVignetteRep.getRadiusY() * h));
}
mEditorVignette.commitLocalRepresentation();
}
@@ -150,15 +154,17 @@
if (mVignetteRep == null) {
return;
}
+ float w = MasterImage.getImage().getOriginalBounds().width();
+ float h = MasterImage.getImage().getOriginalBounds().height();
Matrix toImg = getScreenToImageMatrix(false);
Matrix toScr = new Matrix();
toImg.invert(toScr);
float[] c = new float[] {
- mVignetteRep.getCenterX(), mVignetteRep.getCenterY() };
+ mVignetteRep.getCenterX() * w, mVignetteRep.getCenterY() * h };
toScr.mapPoints(c);
mElipse.setCenter(c[0], c[1]);
- mElipse.setRadius(toScr.mapRadius(mVignetteRep.getRadiusX()),
- toScr.mapRadius(mVignetteRep.getRadiusY()));
+ mElipse.setRadius(toScr.mapRadius(mVignetteRep.getRadiusX() * w),
+ toScr.mapRadius(mVignetteRep.getRadiusY() * h));
mElipse.draw(canvas);
}