summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/filtershow/filters
diff options
context:
space:
mode:
authorJohn Hoford <hoford@google.com>2013-08-27 17:18:50 -0700
committerJohn Hoford <hoford@google.com>2013-08-29 11:13:36 -0700
commit37f8e432f4eb94d0ab483bfdc2a1fa024508e85f (patch)
treeffba4df533e758c6a7f9c6c1ef3471dbf75e59d8 /src/com/android/gallery3d/filtershow/filters
parente40690d73eb611f3f461f51a2841e73bcbd01f79 (diff)
downloadandroid_packages_apps_Gallery2-37f8e432f4eb94d0ab483bfdc2a1fa024508e85f.tar.gz
android_packages_apps_Gallery2-37f8e432f4eb94d0ab483bfdc2a1fa024508e85f.tar.bz2
android_packages_apps_Gallery2-37f8e432f4eb94d0ab483bfdc2a1fa024508e85f.zip
vignette fix & enhance to remove center focus
Change-Id: Ide19925c5a9113518815d3aacc2204ef5ab9661d
Diffstat (limited to 'src/com/android/gallery3d/filtershow/filters')
-rw-r--r--src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java188
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java114
-rw-r--r--src/com/android/gallery3d/filtershow/filters/vignette.rs78
3 files changed, 303 insertions, 77 deletions
diff --git a/src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java
index 8429d3b5e..2e362f8b5 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 @@ public class FilterVignetteRepresentation extends FilterBasicRepresentation impl
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 @@ public class FilterVignetteRepresentation extends FilterBasicRepresentation impl
@Override
public boolean isNil() {
- return getValue() == 0;
+ return false;
}
@Override
@@ -126,6 +166,10 @@ public class FilterVignetteRepresentation extends FilterBasicRepresentation impl
}
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 @@ public class FilterVignetteRepresentation extends FilterBasicRepresentation impl
return false;
}
- private static final String[] sParams = {
- "Name", "value", "mCenterX", "mCenterY", "mRadiusX",
- "mRadiusY"
- };
-
- @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;
- }
-
- @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);
+ private static final String ELLIPSE = "ellipse";
+ private static final String ARGS = "adjust";
+ @Override
+ 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(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 7e0a452bf..0ab5016cd 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java
@@ -19,14 +19,26 @@ package com.android.gallery3d.filtershow.filters;
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 @@ public class ImageFilterVignette extends SimpleImageFilter {
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 @@ public class ImageFilterVignette extends SimpleImageFilter {
}
@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 @@ public class ImageFilterVignette extends SimpleImageFilter {
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 000000000..709b220e4
--- /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