diff options
author | nicolasroard <nicolasroard@google.com> | 2012-09-25 14:27:56 -0700 |
---|---|---|
committer | nicolasroard <nicolasroard@google.com> | 2012-09-26 16:13:45 -0700 |
commit | 4cc4609f572bb0e98328735c19619211b75a4091 (patch) | |
tree | 52562ae1c3978f6d75854db1982f226600212b7c /src/com/android/gallery3d | |
parent | 9aab1ed0edf0faf8623390584445eac694a0ece9 (diff) | |
download | android_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')
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); + } + +} |