summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/filtershow
diff options
context:
space:
mode:
authornicolasroard <nicolasroard@google.com>2012-09-25 14:27:56 -0700
committernicolasroard <nicolasroard@google.com>2012-09-26 16:13:45 -0700
commit4cc4609f572bb0e98328735c19619211b75a4091 (patch)
tree52562ae1c3978f6d75854db1982f226600212b7c /src/com/android/gallery3d/filtershow
parent9aab1ed0edf0faf8623390584445eac694a0ece9 (diff)
downloadandroid_packages_apps_Snap-4cc4609f572bb0e98328735c19619211b75a4091.tar.gz
android_packages_apps_Snap-4cc4609f572bb0e98328735c19619211b75a4091.tar.bz2
android_packages_apps_Snap-4cc4609f572bb0e98328735c19619211b75a4091.zip
Initial import of the new image editor
bug:7165910 Change-Id: I756d6594f5bddd233772c979410362ca22e232a3
Diffstat (limited to 'src/com/android/gallery3d/filtershow')
-rw-r--r--src/com/android/gallery3d/filtershow/cache/DelayedPresetCache.java59
-rw-r--r--src/com/android/gallery3d/filtershow/cache/DirectPresetCache.java144
-rw-r--r--src/com/android/gallery3d/filtershow/presets/ImagePreset.java193
-rw-r--r--src/com/android/gallery3d/filtershow/presets/ImagePresetBW.java16
-rw-r--r--src/com/android/gallery3d/filtershow/presets/ImagePresetBWBlue.java16
-rw-r--r--src/com/android/gallery3d/filtershow/presets/ImagePresetBWGreen.java16
-rw-r--r--src/com/android/gallery3d/filtershow/presets/ImagePresetBWRed.java16
-rw-r--r--src/com/android/gallery3d/filtershow/presets/ImagePresetOld.java21
-rw-r--r--src/com/android/gallery3d/filtershow/presets/ImagePresetSaturated.java16
-rw-r--r--src/com/android/gallery3d/filtershow/presets/ImagePresetXProcessing.java22
10 files changed, 519 insertions, 0 deletions
diff --git a/src/com/android/gallery3d/filtershow/cache/DelayedPresetCache.java b/src/com/android/gallery3d/filtershow/cache/DelayedPresetCache.java
new file mode 100644
index 000000000..8acb539b6
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/cache/DelayedPresetCache.java
@@ -0,0 +1,59 @@
+
+package com.android.gallery3d.filtershow.cache;
+
+import android.os.Handler;
+import android.os.Handler.Callback;
+import android.os.HandlerThread;
+import android.os.Message;
+import android.os.Process;
+
+public class DelayedPresetCache extends DirectPresetCache implements Callback {
+ private HandlerThread mHandlerThread = null;
+
+ private final static int NEW_PRESET = 0;
+ private final static int COMPUTE_PRESET = 1;
+
+ private Handler mProcessingHandler = null;
+ private Handler mUIHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case NEW_PRESET: {
+ CachedPreset cache = (CachedPreset) msg.obj;
+ didCompute(cache);
+ break;
+ }
+ }
+ }
+ };
+
+ @Override
+ public boolean handleMessage(Message msg) {
+ switch (msg.what) {
+ case COMPUTE_PRESET: {
+ CachedPreset cache = (CachedPreset) msg.obj;
+ compute(cache);
+ Message uimsg = mUIHandler.obtainMessage(NEW_PRESET, cache);
+ mUIHandler.sendMessage(uimsg);
+ break;
+ }
+ }
+ return false;
+ }
+
+ public DelayedPresetCache(int size) {
+ super(size);
+ mHandlerThread = new HandlerThread("ImageProcessing", Process.THREAD_PRIORITY_BACKGROUND);
+ mHandlerThread.start();
+ mProcessingHandler = new Handler(mHandlerThread.getLooper(), this);
+ }
+
+ protected void willCompute(CachedPreset cache) {
+ if (cache == null) {
+ return;
+ }
+ cache.setBusy(true);
+ Message msg = mProcessingHandler.obtainMessage(COMPUTE_PRESET, cache);
+ mProcessingHandler.sendMessage(msg);
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/cache/DirectPresetCache.java b/src/com/android/gallery3d/filtershow/cache/DirectPresetCache.java
new file mode 100644
index 000000000..1ba835673
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/cache/DirectPresetCache.java
@@ -0,0 +1,144 @@
+
+package com.android.gallery3d.filtershow.cache;
+
+import java.util.Vector;
+
+import android.graphics.Bitmap;
+import android.util.Log;
+
+import com.android.gallery3d.filtershow.imageshow.ImageShow;
+import com.android.gallery3d.filtershow.presets.ImagePreset;
+
+public class DirectPresetCache implements Cache {
+
+ private static final String LOGTAG = "DirectPresetCache";
+ private Bitmap mOriginalBitmap = null;
+ private Vector<ImageShow> mObservers = new Vector<ImageShow>();
+ private Vector<CachedPreset> mCache = new Vector<CachedPreset>();
+ private int mCacheSize = 1;
+ private Bitmap.Config mBitmapConfig = Bitmap.Config.ARGB_8888;
+ private long mGlobalAge = 0;
+
+ protected class CachedPreset {
+ private Bitmap mBitmap = null;
+ private ImagePreset mPreset = null;
+ private long mAge = 0;
+ private boolean mBusy = false;
+
+ public void setBusy(boolean value) {
+ mBusy = value;
+ }
+
+ public boolean busy() {
+ return mBusy;
+ }
+ }
+
+ public DirectPresetCache(int size) {
+ mCacheSize = size;
+ }
+
+ public void setOriginalBitmap(Bitmap bitmap) {
+ mOriginalBitmap = bitmap;
+ notifyObservers();
+ }
+
+ public void notifyObservers() {
+ for (int i = 0; i < mObservers.size(); i++) {
+ ImageShow imageShow = mObservers.elementAt(i);
+ imageShow.invalidate();
+ }
+ }
+
+ public void addObserver(ImageShow observer) {
+ if (!mObservers.contains(observer)) {
+ mObservers.add(observer);
+ }
+ }
+
+ private CachedPreset getCachedPreset(ImagePreset preset) {
+ for (int i = 0; i < mCache.size(); i++) {
+ CachedPreset cache = mCache.elementAt(i);
+ if (cache.mPreset == preset && !cache.mBusy) {
+ return cache;
+ }
+ }
+ return null;
+ }
+
+ public Bitmap get(ImagePreset preset) {
+ // Log.v(LOGTAG, "get preset " + preset.name() + " : " + preset);
+ CachedPreset cache = getCachedPreset(preset);
+ if (cache != null) {
+ return cache.mBitmap;
+ }
+ // Log.v(LOGTAG, "didn't find preset " + preset.name() + " : " + preset
+ // + " we have " + mCache.size() + " elts / " + mCacheSize);
+ return null;
+ }
+
+ public void reset(ImagePreset preset) {
+ CachedPreset cache = getCachedPreset(preset);
+ if (cache != null && !cache.mBusy) {
+ cache.mBitmap = null;
+ willCompute(cache);
+ }
+ }
+
+ private CachedPreset getOldestCachedPreset() {
+ CachedPreset found = null;
+ for (int i = 0; i < mCache.size(); i++) {
+ CachedPreset cache = mCache.elementAt(i);
+ if (cache.mBusy) {
+ continue;
+ }
+ if (found == null) {
+ found = cache;
+ } else {
+ if (found.mAge > cache.mAge) {
+ found = cache;
+ }
+ }
+ }
+ return found;
+ }
+
+ protected void willCompute(CachedPreset cache) {
+ if (cache == null) {
+ return;
+ }
+ cache.mBusy = true;
+ compute(cache);
+ didCompute(cache);
+ }
+
+ protected void didCompute(CachedPreset cache) {
+ cache.mBusy = false;
+ notifyObservers();
+ }
+
+ protected void compute(CachedPreset cache) {
+ cache.mBitmap = null;
+ cache.mBitmap = mOriginalBitmap.copy(mBitmapConfig, true);
+ cache.mPreset.apply(cache.mBitmap);
+ cache.mAge = mGlobalAge++;
+ }
+
+ public void prepare(ImagePreset preset) {
+ // Log.v(LOGTAG, "prepare preset " + preset.name() + " : " + preset);
+ CachedPreset cache = getCachedPreset(preset);
+ if (cache == null) {
+ if (mCache.size() < mCacheSize) {
+ cache = new CachedPreset();
+ mCache.add(cache);
+ } else {
+ cache = getOldestCachedPreset();
+ }
+ if (cache != null) {
+ cache.mPreset = preset;
+ }
+ }
+ willCompute(cache);
+ }
+
+}
diff --git a/src/com/android/gallery3d/filtershow/presets/ImagePreset.java b/src/com/android/gallery3d/filtershow/presets/ImagePreset.java
new file mode 100644
index 000000000..302b94bed
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/presets/ImagePreset.java
@@ -0,0 +1,193 @@
+
+package com.android.gallery3d.filtershow.presets;
+
+import java.util.Vector;
+
+import android.graphics.Bitmap;
+import android.graphics.RectF;
+import android.util.Log;
+
+import com.android.gallery3d.filtershow.filters.ImageFilter;
+import com.android.gallery3d.filtershow.filters.ImageFilterStraighten;
+import com.android.gallery3d.filtershow.imageshow.ImageShow;
+
+public class ImagePreset {
+
+ private static final String LOGTAG = "ImagePreset";
+ ImageShow mEndPoint = null;
+ protected int mParameter = 50;
+ protected Vector<ImageFilter> mFilters = new Vector<ImageFilter>();
+ protected String mName = "Original";
+ protected String mHistoryName = "Original";
+ protected boolean mIsFxPreset = false;
+
+ enum FullRotate {
+ ZERO, NINETY, HUNDRED_HEIGHTY, TWO_HUNDRED_SEVENTY
+ }
+
+ protected FullRotate mFullRotate = FullRotate.ZERO;
+ protected float mStraightenRotate = 0;
+ protected float mStraightenZoom = 0;
+ protected boolean mHorizontalFlip = false;
+ protected boolean mVerticalFlip = false;
+ protected RectF mCrop = null;
+
+ public ImagePreset() {
+ setup();
+ }
+
+ public ImagePreset(ImagePreset source) {
+ for (int i = 0; i < source.mFilters.size(); i++) {
+ add(source.mFilters.elementAt(i).copy());
+ }
+ mName = source.name();
+ mHistoryName = source.name();
+ mIsFxPreset = source.isFx();
+
+ mStraightenRotate = source.mStraightenRotate;
+ mStraightenZoom = source.mStraightenZoom;
+ }
+
+ public void setStraightenRotation(float rotate, float zoom) {
+ mStraightenRotate = rotate;
+ mStraightenZoom = zoom;
+ }
+
+ private Bitmap applyGeometry(Bitmap original) {
+ Bitmap bitmap = original;
+
+ if (mFullRotate != FullRotate.ZERO) {
+ // TODO
+ }
+
+// Log.v(LOGTAG, "applyGeometry with rotate " + mStraightenRotate + " and zoom "
+ // + mStraightenZoom);
+
+ if (mStraightenRotate != 0) {
+ // TODO: keep the instances around
+ ImageFilter straighten = new ImageFilterStraighten(mStraightenRotate, mStraightenZoom);
+ straighten.apply(bitmap);
+ straighten = null;
+ }
+
+ return bitmap;
+ }
+
+ public boolean isFx() {
+ return mIsFxPreset;
+ }
+
+ public void setIsFx(boolean value) {
+ mIsFxPreset = value;
+ }
+
+ public void setName(String name) {
+ mName = name;
+ mHistoryName = name;
+ }
+
+ public void setHistoryName(String name) {
+ mHistoryName = name;
+ }
+
+ public boolean same(ImagePreset preset) {
+ if (preset.mFilters.size() != mFilters.size()) {
+ return false;
+ }
+ if (!mName.equalsIgnoreCase(preset.name())) {
+ return false;
+ }
+ if (mStraightenRotate != preset.mStraightenRotate) {
+ return false;
+ }
+ for (int i = 0; i < preset.mFilters.size(); i++) {
+ ImageFilter a = preset.mFilters.elementAt(i);
+ ImageFilter b = mFilters.elementAt(i);
+ if (!a.same(b)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public String name() {
+ return mName;
+ }
+
+ public String historyName() {
+ return mHistoryName;
+ }
+
+ public void add(ImageFilter preset) {
+ mFilters.add(preset);
+ }
+
+ public void remove(String filterName) {
+ ImageFilter filter = getFilter(filterName);
+ if (filter != null) {
+ mFilters.remove(filter);
+ }
+ }
+
+ public int getCount() {
+ return mFilters.size();
+ }
+
+ public ImageFilter getFilter(String name) {
+ for (int i = 0; i < mFilters.size(); i++) {
+ ImageFilter filter = mFilters.elementAt(i);
+ if (filter.name().equalsIgnoreCase(name)) {
+ return filter;
+ }
+ }
+ return null;
+ }
+
+ public void setup() {
+ // do nothing here
+ }
+
+ public void setEndpoint(ImageShow image) {
+ mEndPoint = image;
+ }
+
+ public Bitmap apply(Bitmap original) {
+ // First we apply any transform -- 90 rotate, flip, straighten, crop
+ Bitmap bitmap = applyGeometry(original);
+
+ // TODO -- apply borders separately
+ ImageFilter borderFilter = null;
+ for (int i = 0; i < mFilters.size(); i++) {
+ ImageFilter filter = mFilters.elementAt(i);
+ if (filter.name().equalsIgnoreCase("Border")) {
+ // TODO don't use the name as an id
+ borderFilter = filter;
+ } else {
+ filter.apply(bitmap);
+ }
+ }
+ if (borderFilter != null) {
+ borderFilter.apply(bitmap);
+ }
+ if (mEndPoint != null) {
+ mEndPoint.updateFilteredImage(bitmap);
+ }
+ return bitmap;
+ }
+
+ /*
+ * public void applyFilter(Bitmap bitmap) { // do nothing here, subclasses
+ * will implement filtering here } native protected void
+ * nativeApplyGradientFilter(Bitmap bitmap, int w, int h, int[] redGradient,
+ * int[] greenGradient, int[] blueGradient);
+ */
+
+ public void setParameter(int value) {
+ mParameter = value;
+ for (int i = 0; i < mFilters.size(); i++) {
+ ImageFilter filter = mFilters.elementAt(i);
+ filter.setParameter(value);
+ }
+ }
+
+}
diff --git a/src/com/android/gallery3d/filtershow/presets/ImagePresetBW.java b/src/com/android/gallery3d/filtershow/presets/ImagePresetBW.java
new file mode 100644
index 000000000..a270080f9
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/presets/ImagePresetBW.java
@@ -0,0 +1,16 @@
+
+package com.android.gallery3d.filtershow.presets;
+
+import com.android.gallery3d.filtershow.filters.ImageFilterBW;
+
+public class ImagePresetBW extends ImagePreset {
+
+ public String name() {
+ return "Black & White";
+ }
+
+ public void setup() {
+ mFilters.add(new ImageFilterBW());
+ }
+
+}
diff --git a/src/com/android/gallery3d/filtershow/presets/ImagePresetBWBlue.java b/src/com/android/gallery3d/filtershow/presets/ImagePresetBWBlue.java
new file mode 100644
index 000000000..1783b482b
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/presets/ImagePresetBWBlue.java
@@ -0,0 +1,16 @@
+
+package com.android.gallery3d.filtershow.presets;
+
+import com.android.gallery3d.filtershow.filters.ImageFilterBWBlue;
+
+public class ImagePresetBWBlue extends ImagePreset {
+
+ public String name() {
+ return "Black & White (Blue)";
+ }
+
+ public void setup() {
+ mFilters.add(new ImageFilterBWBlue());
+ }
+
+}
diff --git a/src/com/android/gallery3d/filtershow/presets/ImagePresetBWGreen.java b/src/com/android/gallery3d/filtershow/presets/ImagePresetBWGreen.java
new file mode 100644
index 000000000..5b317a1e0
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/presets/ImagePresetBWGreen.java
@@ -0,0 +1,16 @@
+
+package com.android.gallery3d.filtershow.presets;
+
+import com.android.gallery3d.filtershow.filters.ImageFilterBWGreen;
+
+public class ImagePresetBWGreen extends ImagePreset {
+
+ public String name() {
+ return "Black & White (Green)";
+ }
+
+ public void setup() {
+ mFilters.add(new ImageFilterBWGreen());
+ }
+
+}
diff --git a/src/com/android/gallery3d/filtershow/presets/ImagePresetBWRed.java b/src/com/android/gallery3d/filtershow/presets/ImagePresetBWRed.java
new file mode 100644
index 000000000..7b9f0e141
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/presets/ImagePresetBWRed.java
@@ -0,0 +1,16 @@
+
+package com.android.gallery3d.filtershow.presets;
+
+import com.android.gallery3d.filtershow.filters.ImageFilterBWRed;
+
+public class ImagePresetBWRed extends ImagePreset {
+
+ public String name() {
+ return "Black & White (Red)";
+ }
+
+ public void setup() {
+ mFilters.add(new ImageFilterBWRed());
+ }
+
+}
diff --git a/src/com/android/gallery3d/filtershow/presets/ImagePresetOld.java b/src/com/android/gallery3d/filtershow/presets/ImagePresetOld.java
new file mode 100644
index 000000000..56e1dab45
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/presets/ImagePresetOld.java
@@ -0,0 +1,21 @@
+
+package com.android.gallery3d.filtershow.presets;
+
+import com.android.gallery3d.filtershow.filters.ImageFilterGradient;
+
+import android.graphics.Color;
+
+public class ImagePresetOld extends ImagePreset {
+
+ public String name() {
+ return "Old";
+ }
+
+ public void setup() {
+ ImageFilterGradient filter = new ImageFilterGradient();
+ filter.addColor(Color.BLACK, 0.0f);
+ filter.addColor(Color.argb(255, 228, 231, 193), 1.0f);
+ mFilters.add(filter);
+ }
+
+}
diff --git a/src/com/android/gallery3d/filtershow/presets/ImagePresetSaturated.java b/src/com/android/gallery3d/filtershow/presets/ImagePresetSaturated.java
new file mode 100644
index 000000000..cf280ee47
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/presets/ImagePresetSaturated.java
@@ -0,0 +1,16 @@
+
+package com.android.gallery3d.filtershow.presets;
+
+import com.android.gallery3d.filtershow.filters.ImageFilterSaturated;
+
+public class ImagePresetSaturated extends ImagePreset {
+
+ public String name() {
+ return "Saturated";
+ }
+
+ public void setup() {
+ mFilters.add(new ImageFilterSaturated());
+ }
+
+}
diff --git a/src/com/android/gallery3d/filtershow/presets/ImagePresetXProcessing.java b/src/com/android/gallery3d/filtershow/presets/ImagePresetXProcessing.java
new file mode 100644
index 000000000..3e744be77
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/presets/ImagePresetXProcessing.java
@@ -0,0 +1,22 @@
+
+package com.android.gallery3d.filtershow.presets;
+
+import com.android.gallery3d.filtershow.filters.ImageFilterGradient;
+
+import android.graphics.Color;
+
+public class ImagePresetXProcessing extends ImagePreset {
+
+ public String name() {
+ return "X-Process";
+ }
+
+ public void setup() {
+ ImageFilterGradient filter = new ImageFilterGradient();
+ filter.addColor(Color.BLACK, 0.0f);
+ filter.addColor(Color.argb(255, 29, 82, 83), 0.4f);
+ filter.addColor(Color.argb(255, 211, 217, 186), 1.0f);
+ mFilters.add(filter);
+ }
+
+}