diff options
author | John Hoford <hoford@google.com> | 2013-08-27 17:18:50 -0700 |
---|---|---|
committer | John Hoford <hoford@google.com> | 2013-08-29 11:13:36 -0700 |
commit | 37f8e432f4eb94d0ab483bfdc2a1fa024508e85f (patch) | |
tree | ffba4df533e758c6a7f9c6c1ef3471dbf75e59d8 /src/com/android/gallery3d/filtershow/filters | |
parent | e40690d73eb611f3f461f51a2841e73bcbd01f79 (diff) | |
download | android_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')
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 |