summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Hoford <hoford@google.com>2012-09-27 16:34:21 -0700
committerJohn Hoford <hoford@google.com>2012-09-28 17:14:13 -0700
commitfc275d4e972304a8c4935d6161c74cbbbdf600ae (patch)
treeb3ab74a2ac51667cb857b61b573b4f66a5502e41
parente83215c9a82c811b61357091ff2ba45e5ba08092 (diff)
downloadandroid_packages_apps_Snap-fc275d4e972304a8c4935d6161c74cbbbdf600ae.tar.gz
android_packages_apps_Snap-fc275d4e972304a8c4935d6161c74cbbbdf600ae.tar.bz2
android_packages_apps_Snap-fc275d4e972304a8c4935d6161c74cbbbdf600ae.zip
Add contrast & brightness filters
Added hue fixed contrast Stablized Contrast, Saturation, Tint, Exposure bug:7234321 Change-Id: Iadd1e3ab215b60f920b718fa56611a07f24effee
-rw-r--r--src/com/android/gallery3d/filtershow/FilterShowActivity.java169
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ColorSpaceMatrix.java201
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterBrightness.java25
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java25
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java29
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java4
6 files changed, 449 insertions, 4 deletions
diff --git a/src/com/android/gallery3d/filtershow/FilterShowActivity.java b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
index 43ff67750..589d5731b 100644
--- a/src/com/android/gallery3d/filtershow/FilterShowActivity.java
+++ b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
@@ -65,7 +65,13 @@ public class FilterShowActivity extends Activity implements OnItemClickListener
private ImageButton mCurvesButtonGreen = null;
private ImageButton mCurvesButtonBlue = null;
private ImageButton mSharpenButton = null;
+
private ImageButton mContrastButton = null;
+ private ImageButton mSaturationButton = null;
+ private ImageButton mTintButton = null;
+ private ImageButton mVibranceButton = null;
+ private ImageButton mExposureButton = null;
+ private ImageButton mShadowRecoveryButton = null;
private static final int SELECT_PICTURE = 1;
private static final String LOGTAG = "FilterShowActivity";
@@ -133,7 +139,13 @@ public class FilterShowActivity extends Activity implements OnItemClickListener
mCurvesButtonGreen = (ImageButton) findViewById(R.id.curvesButtonGreen);
mCurvesButtonBlue = (ImageButton) findViewById(R.id.curvesButtonBlue);
mSharpenButton = (ImageButton) findViewById(R.id.sharpenButton);
+ mVibranceButton = (ImageButton) findViewById(R.id.vibranceButton);
mContrastButton = (ImageButton) findViewById(R.id.contrastButton);
+ mSaturationButton = (ImageButton) findViewById(R.id.saturationButton);
+ mTintButton = (ImageButton) findViewById(R.id.tintButton);
+ mExposureButton = (ImageButton) findViewById(R.id.exposureButton);
+ mShadowRecoveryButton = (ImageButton) findViewById(R.id.shadowRecoveryButton);
+
mColorsPanelButtons.add(mVignetteButton);
mColorsPanelButtons.add(mCurvesButtonRGB);
mColorsPanelButtons.add(mCurvesButtonRed);
@@ -141,6 +153,11 @@ public class FilterShowActivity extends Activity implements OnItemClickListener
mColorsPanelButtons.add(mCurvesButtonBlue);
mColorsPanelButtons.add(mSharpenButton);
mColorsPanelButtons.add(mContrastButton);
+ mColorsPanelButtons.add(mSaturationButton);
+ mColorsPanelButtons.add(mTintButton);
+ mColorsPanelButtons.add(mVibranceButton);
+ mColorsPanelButtons.add(mExposureButton);
+ mColorsPanelButtons.add(mShadowRecoveryButton);
mCurvesButtonRGB.setSelected(true);
@@ -160,6 +177,12 @@ public class FilterShowActivity extends Activity implements OnItemClickListener
mSharpenButton.setOnClickListener(createOnClickSharpenButton());
mContrastButton.setOnClickListener(createOnClickContrastButton());
+ mSaturationButton.setOnClickListener(createOnClickSaturationButton());
+
+ mTintButton.setOnClickListener(createOnClickTintButton());
+ mVibranceButton.setOnClickListener(createOnClickVibranceButton());
+ mExposureButton.setOnClickListener(createOnClickExposureButton());
+ mShadowRecoveryButton.setOnClickListener(createOnClickShadowRecoveryButton());
mFxButton.setOnClickListener(createOnClickFxButton());
mBorderButton.setOnClickListener(createOnClickBorderButton());
@@ -648,14 +671,156 @@ public class FilterShowActivity extends Activity implements OnItemClickListener
public void onClick(View v) {
hideImageViews();
mImageShow.setVisibility(View.VISIBLE);
+ mImageShow.setShowControls(true);
+ ImagePreset preset = mImageShow.getImagePreset();
+ ImageFilter filter = preset.getFilter("Contrast");
+ if (filter == null) {
+ ImageFilterContrast contrast = new ImageFilterContrast();
+ ImagePreset copy = new ImagePreset(preset);
+ copy.add(contrast);
+ copy.setHistoryName(contrast.name());
+ copy.setIsFx(false);
+ filter = copy.getFilter("Contrast");
+ mImageShow.setImagePreset(copy);
+ }
+ mImageShow.setCurrentFilter(filter);
unselectPanelButtons(mColorsPanelButtons);
mContrastButton.setSelected(true);
- mImageShow.showToast("Contrast", true);
- mImageShow.setCurrentFilter(null);
+ invalidateViews();
}
};
}
+ private OnClickListener createOnClickSaturationButton() {
+ return new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ hideImageViews();
+ mImageShow.setVisibility(View.VISIBLE);
+ mImageShow.setShowControls(true);
+ ImagePreset preset = mImageShow.getImagePreset();
+ ImageFilter filter = preset.getFilter("Saturated");
+ if (filter == null) {
+ ImageFilterSaturated sat = new ImageFilterSaturated();
+ ImagePreset copy = new ImagePreset(preset);
+ copy.add(sat);
+ copy.setHistoryName(sat.name());
+ copy.setIsFx(false);
+ filter = copy.getFilter("Saturated");
+ mImageShow.setImagePreset(copy);
+ }
+ mImageShow.setCurrentFilter(filter);
+ unselectPanelButtons(mColorsPanelButtons);
+ mSaturationButton.setSelected(true);
+ invalidateViews();
+ }
+ };
+ }
+
+ private OnClickListener createOnClickTintButton() {
+ return new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ hideImageViews();
+ mImageShow.setVisibility(View.VISIBLE);
+ mImageShow.setShowControls(true);
+ ImagePreset preset = mImageShow.getImagePreset();
+ ImageFilter filter = preset.getFilter("Hue");
+ if (filter == null) {
+ ImageFilterHue contrast = new ImageFilterHue();
+ ImagePreset copy = new ImagePreset(preset);
+ copy.add(contrast);
+ copy.setHistoryName(contrast.name());
+ copy.setIsFx(false);
+ filter = copy.getFilter("Hue");
+ mImageShow.setImagePreset(copy);
+ }
+ mImageShow.setCurrentFilter(filter);
+ unselectPanelButtons(mColorsPanelButtons);
+ mTintButton.setSelected(true);
+ invalidateViews();
+ }
+ };
+ }
+
+ private OnClickListener createOnClickVibranceButton() {
+ return new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ hideImageViews();
+ mImageShow.setVisibility(View.VISIBLE);
+ mImageShow.setShowControls(true);
+ ImagePreset preset = mImageShow.getImagePreset();
+ ImageFilter filter = preset.getFilter("Hue");
+ if (filter == null) {
+ ImageFilterHue contrast = new ImageFilterHue();
+ ImagePreset copy = new ImagePreset(preset);
+ copy.add(contrast);
+ copy.setHistoryName(contrast.name());
+ copy.setIsFx(false);
+ filter = copy.getFilter("Hue");
+ mImageShow.setImagePreset(copy);
+ }
+ mImageShow.setCurrentFilter(filter);
+ unselectPanelButtons(mColorsPanelButtons);
+ mVibranceButton.setSelected(true);
+ invalidateViews();
+ }
+ };
+ }
+
+ private OnClickListener createOnClickExposureButton() {
+ return new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ hideImageViews();
+ mImageShow.setVisibility(View.VISIBLE);
+ mImageShow.setShowControls(true);
+ ImagePreset preset = mImageShow.getImagePreset();
+ ImageFilter filter = preset.getFilter("Brightness");
+ if (filter == null) {
+ ImageFilterBrightness bright = new ImageFilterBrightness();
+ ImagePreset copy = new ImagePreset(preset);
+ copy.add(bright);
+ copy.setHistoryName(bright.name());
+ copy.setIsFx(false);
+ filter = copy.getFilter("Brightness");
+ mImageShow.setImagePreset(copy);
+ }
+ mImageShow.setCurrentFilter(filter);
+ unselectPanelButtons(mColorsPanelButtons);
+ mExposureButton.setSelected(true);
+ invalidateViews();
+ }
+ };
+ }
+
+ private OnClickListener createOnClickShadowRecoveryButton() {
+ return new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ hideImageViews();
+ mImageShow.setVisibility(View.VISIBLE);
+ mImageShow.setShowControls(true);
+ ImagePreset preset = mImageShow.getImagePreset();
+ ImageFilter filter = preset.getFilter("Hue");
+ if (filter == null) {
+ ImageFilterHue contrast = new ImageFilterHue();
+ ImagePreset copy = new ImagePreset(preset);
+ copy.add(contrast);
+ copy.setHistoryName(contrast.name());
+ copy.setIsFx(false);
+ filter = copy.getFilter("Hue");
+ mImageShow.setImagePreset(copy);
+ }
+ mImageShow.setCurrentFilter(filter);
+ unselectPanelButtons(mColorsPanelButtons);
+ mShadowRecoveryButton.setSelected(true);
+ invalidateViews();
+ }
+ };
+ }
+
// //////////////////////////////////////////////////////////////////////////////
public float getPixelsFromDip(float value) {
diff --git a/src/com/android/gallery3d/filtershow/filters/ColorSpaceMatrix.java b/src/com/android/gallery3d/filtershow/filters/ColorSpaceMatrix.java
new file mode 100644
index 000000000..f03a04569
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/filters/ColorSpaceMatrix.java
@@ -0,0 +1,201 @@
+
+package com.android.gallery3d.filtershow.filters;
+
+import java.util.Arrays;
+
+public class ColorSpaceMatrix {
+ private final float[] matrix = new float[16];
+ private static final float RLUM = 0.3086f;
+ private static final float GLUM = 0.6094f;
+ private static final float BLUM = 0.0820f;
+
+ public ColorSpaceMatrix() {
+ identity();
+ }
+
+ /**
+ * get the matrix
+ *
+ * @return the internal matrix
+ */
+ public float[] getMatrix() {
+ return matrix;
+ }
+
+ /**
+ * set matrix to identity
+ */
+ public void identity() {
+ Arrays.fill(matrix, 0);
+ matrix[0] = matrix[5] = matrix[10] = matrix[15] = 1;
+ }
+
+ public void convertToLuminance() {
+ matrix[0] = matrix[1] = matrix[2] = 0.3086f;
+ matrix[4] = matrix[5] = matrix[6] = 0.6094f;
+ matrix[8] = matrix[9] = matrix[10] = 0.0820f;
+ }
+
+ private void multiply(float[] a)
+ {
+ int x, y;
+ float[] temp = new float[16];
+
+ for (y = 0; y < 4; y++) {
+ int y4 = y * 4;
+ for (x = 0; x < 4; x++) {
+ temp[y4 + x] = matrix[y4 + 0] * a[x]
+ + matrix[y4 + 1] * a[4 + x]
+ + matrix[y4 + 2] * a[8 + x]
+ + matrix[y4 + 3] * a[12 + x];
+ }
+ }
+ for (int i = 0; i < 16; i++)
+ matrix[i] = temp[i];
+ }
+
+ private void xRotateMatrix(float rs, float rc)
+ {
+ ColorSpaceMatrix c = new ColorSpaceMatrix();
+ float[] tmp = c.matrix;
+
+ tmp[5] = rc;
+ tmp[6] = rs;
+ tmp[9] = -rs;
+ tmp[10] = rc;
+
+ multiply(tmp);
+ }
+
+ private void yRotateMatrix(float rs, float rc)
+ {
+ ColorSpaceMatrix c = new ColorSpaceMatrix();
+ float[] tmp = c.matrix;
+
+ tmp[0] = rc;
+ tmp[2] = -rs;
+ tmp[8] = rs;
+ tmp[10] = rc;
+
+ multiply(tmp);
+ }
+
+ private void zRotateMatrix(float rs, float rc)
+ {
+ ColorSpaceMatrix c = new ColorSpaceMatrix();
+ float[] tmp = c.matrix;
+
+ tmp[0] = rc;
+ tmp[1] = rs;
+ tmp[4] = -rs;
+ tmp[5] = rc;
+ multiply(tmp);
+ }
+
+ private void zShearMatrix(float dx, float dy)
+ {
+ ColorSpaceMatrix c = new ColorSpaceMatrix();
+ float[] tmp = c.matrix;
+
+ tmp[2] = dx;
+ tmp[6] = dy;
+ multiply(tmp);
+ }
+
+ /**
+ * sets the transform to a shift in Hue
+ *
+ * @param rot rotation in degrees
+ */
+ public void setHue(float rot)
+ {
+ float mag = (float) Math.sqrt(2.0);
+ float xrs = 1 / mag;
+ float xrc = 1 / mag;
+ xRotateMatrix(xrs, xrc);
+ mag = (float) Math.sqrt(3.0);
+ float yrs = -1 / mag;
+ float yrc = (float) Math.sqrt(2.0) / mag;
+ yRotateMatrix(yrs, yrc);
+
+ float lx = getRedf(RLUM, GLUM, BLUM);
+ float ly = getGreenf(RLUM, GLUM, BLUM);
+ float lz = getBluef(RLUM, GLUM, BLUM);
+ float zsx = lx / lz;
+ float zsy = ly / lz;
+ zShearMatrix(zsx, zsy);
+
+ float zrs = (float) Math.sin(rot * Math.PI / 180.0);
+ float zrc = (float) Math.cos(rot * Math.PI / 180.0);
+ zRotateMatrix(zrs, zrc);
+ zShearMatrix(-zsx, -zsy);
+ yRotateMatrix(-yrs, yrc);
+ xRotateMatrix(-xrs, xrc);
+ }
+
+ /**
+ * set it to a saturation matrix
+ *
+ * @param s
+ */
+ public void changeSaturation(float s) {
+ matrix[0] = (1 - s) * RLUM + s;
+ matrix[1] = (1 - s) * RLUM;
+ matrix[2] = (1 - s) * RLUM;
+ matrix[4] = (1 - s) * GLUM;
+ matrix[5] = (1 - s) * GLUM + s;
+ matrix[6] = (1 - s) * GLUM;
+ matrix[8] = (1 - s) * BLUM;
+ matrix[9] = (1 - s) * BLUM;
+ matrix[10] = (1 - s) * BLUM + s;
+ }
+
+ /**
+ * Transform RGB value
+ *
+ * @param r red pixel value
+ * @param g green pixel value
+ * @param b blue pixel value
+ * @return computed red pixel value
+ */
+ public float getRed(int r, int g, int b) {
+ return r * matrix[0] + g * matrix[4] + b * matrix[8] + matrix[12];
+ }
+
+ /**
+ * Transform RGB value
+ *
+ * @param r red pixel value
+ * @param g green pixel value
+ * @param b blue pixel value
+ * @return computed green pixel value
+ */
+ public float getGreen(int r, int g, int b) {
+ return r * matrix[1] + g * matrix[5] + b * matrix[9] + matrix[13];
+ }
+
+ /**
+ * Transform RGB value
+ *
+ * @param r red pixel value
+ * @param g green pixel value
+ * @param b blue pixel value
+ * @return computed blue pixel value
+ */
+ public float getBlue(int r, int g, int b) {
+ return r * matrix[2] + g * matrix[6] + b * matrix[10] + matrix[14];
+ }
+
+ private float getRedf(float r, float g, float b) {
+ return r * matrix[0] + g * matrix[4] + b * matrix[8] + matrix[12];
+ }
+
+ private float getGreenf(float r, float g, float b) {
+ return r * matrix[1] + g * matrix[5] + b * matrix[9] + matrix[13];
+ }
+
+ private float getBluef(float r, float g, float b) {
+ return r * matrix[2] + g * matrix[6] + b * matrix[10] + matrix[14];
+ }
+
+}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterBrightness.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterBrightness.java
new file mode 100644
index 000000000..8ec4dd061
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterBrightness.java
@@ -0,0 +1,25 @@
+
+package com.android.gallery3d.filtershow.filters;
+
+import android.graphics.Bitmap;
+
+public class ImageFilterBrightness extends ImageFilter {
+
+ public String name() {
+ return "Brightness";
+ }
+
+ public ImageFilter copy() {
+ return new ImageFilterBrightness();
+ }
+
+ native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float bright);
+
+ public void apply(Bitmap bitmap) {
+ int w = bitmap.getWidth();
+ int h = bitmap.getHeight();
+ int p = mParameter;
+ float value = p;
+ nativeApplyFilter(bitmap, w, h, value);
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java
new file mode 100644
index 000000000..dd072cb56
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java
@@ -0,0 +1,25 @@
+
+package com.android.gallery3d.filtershow.filters;
+
+import android.graphics.Bitmap;
+
+public class ImageFilterContrast extends ImageFilter {
+
+ public String name() {
+ return "Contrast";
+ }
+
+ public ImageFilter copy() {
+ return new ImageFilterContrast();
+ }
+
+ native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float strength);
+
+ public void apply(Bitmap bitmap) {
+ int w = bitmap.getWidth();
+ int h = bitmap.getHeight();
+ float p = mParameter;
+ float value = p;
+ nativeApplyFilter(bitmap, w, h, value);
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java
new file mode 100644
index 000000000..154ae2941
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java
@@ -0,0 +1,29 @@
+
+package com.android.gallery3d.filtershow.filters;
+
+import android.graphics.Bitmap;
+
+public class ImageFilterHue extends ImageFilter {
+ private ColorSpaceMatrix cmatrix = new ColorSpaceMatrix();
+
+ public String name() {
+ return "Hue";
+ }
+
+ public ImageFilter copy() {
+ return new ImageFilterHue();
+ }
+
+ native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float []matrix);
+
+ public void apply(Bitmap bitmap) {
+ int w = bitmap.getWidth();
+ int h = bitmap.getHeight();
+ float p = mParameter;
+ float value = p;
+ cmatrix.identity();
+ cmatrix.setHue(value);
+
+ nativeApplyFilter(bitmap, w, h, cmatrix.getMatrix());
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java
index 7c03be68b..f44c6a1c6 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java
@@ -18,8 +18,8 @@ public class ImageFilterSaturated extends ImageFilter {
public void apply(Bitmap bitmap) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
- int p = 100;
- float value = 2 * p / 100.0f;
+ int p = mParameter;
+ float value = 1 + p / 100.0f;
nativeApplyFilter(bitmap, w, h, value);
}
}