summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/android/camera/CaptureAnimManager.java6
-rw-r--r--src/com/android/camera/VideoModule.java6
-rw-r--r--src/com/android/gallery3d/filtershow/FilterShowActivity.java30
-rw-r--r--src/com/android/gallery3d/filtershow/PanelController.java13
-rw-r--r--src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java44
-rw-r--r--src/com/android/gallery3d/filtershow/cache/ImageLoader.java150
-rw-r--r--src/com/android/gallery3d/filtershow/cache/RenderingRequest.java50
-rw-r--r--src/com/android/gallery3d/filtershow/editors/EditorVignette.java55
-rw-r--r--src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java2
-rw-r--r--src/com/android/gallery3d/filtershow/filters/FilterCurvesRepresentation.java1
-rw-r--r--src/com/android/gallery3d/filtershow/filters/FilterDrawRepresentation.java4
-rw-r--r--src/com/android/gallery3d/filtershow/filters/FilterFxRepresentation.java1
-rw-r--r--src/com/android/gallery3d/filtershow/filters/FilterRepresentation.java11
-rw-r--r--src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java114
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterBwFilter.java1
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java1
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterEdge.java1
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterExposure.java1
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterHighlights.java74
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java1
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterKMeans.java1
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterNegative.java1
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java2
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java1
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java1
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterSharpen.java3
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterVibrance.java1
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java60
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterWBalance.java1
-rw-r--r--src/com/android/gallery3d/filtershow/filters/SplineMath.java166
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java256
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageDraw.java36
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImagePoint.java10
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageRedEye.java21
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageShow.java311
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java5
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageTinyPlanet.java5
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageVignette.java142
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageZoom.java14
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/MasterImage.java109
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/Oval.java (renamed from src/com/android/gallery3d/filtershow/ui/SliderListener.java)16
-rw-r--r--src/com/android/gallery3d/filtershow/presets/ImagePreset.java32
-rw-r--r--src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java72
-rw-r--r--src/com/android/gallery3d/filtershow/ui/ImageCurves.java52
-rw-r--r--src/com/android/gallery3d/filtershow/ui/SliderController.java189
-rw-r--r--src_pd/com/android/gallery3d/filtershow/editors/EditorManager.java1
-rwxr-xr-xtests/src/com/android/gallery3d/StressTests.java2
-rwxr-xr-xtests/src/com/android/gallery3d/stress/CameraStressTestRunner.java4
48 files changed, 1565 insertions, 515 deletions
diff --git a/src/com/android/camera/CaptureAnimManager.java b/src/com/android/camera/CaptureAnimManager.java
index 4643c379f..ec38290b3 100644
--- a/src/com/android/camera/CaptureAnimManager.java
+++ b/src/com/android/camera/CaptureAnimManager.java
@@ -33,9 +33,9 @@ public class CaptureAnimManager {
// times mark endpoint of animation phase
private static final int TIME_FLASH = 200;
private static final int TIME_HOLD = 400;
- private static final int TIME_SLIDE = 700;
- private static final int TIME_HOLD2 = 1000;
- private static final int TIME_SLIDE2 = 1200;
+ private static final int TIME_SLIDE = 800;
+ private static final int TIME_HOLD2 = 3300;
+ private static final int TIME_SLIDE2 = 4100;
private static final int ANIM_BOTH = 0;
private static final int ANIM_FLASH = 1;
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index 4d01bc320..245ef5990 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -2216,7 +2216,6 @@ public class VideoModule implements CameraModule,
initializeMiscControls();
showTimeLapseUI(mCaptureTimeLapse);
initializeVideoSnapshot();
- resizeForPreviewAspectRatio();
// from onResume()
showVideoSnapshotUI(false);
@@ -2279,6 +2278,7 @@ public class VideoModule implements CameraModule,
}
private void updateOnScreenIndicators() {
+ if (mParameters == null) return;
updateFlashOnScreenIndicator(mParameters.getFlashMode());
}
@@ -2436,7 +2436,7 @@ public class VideoModule implements CameraModule,
}
private void initializeZoom() {
- if (!mParameters.isZoomSupported()) return;
+ if (mParameters == null || !mParameters.isZoomSupported()) return;
mZoomMax = mParameters.getMaxZoom();
mZoomRatios = mParameters.getZoomRatios();
// Currently we use immediate zoom for fast zooming to get better UX and
@@ -2448,6 +2448,7 @@ public class VideoModule implements CameraModule,
}
private void initializeVideoSnapshot() {
+ if (mParameters == null) return;
if (Util.isVideoSnapshotSupported(mParameters) && !mIsVideoCaptureIntent) {
mActivity.setSingleTapUpListener(mPreviewFrameLayout);
// Show the tap to focus toast if this is the first start.
@@ -2462,6 +2463,7 @@ public class VideoModule implements CameraModule,
}
void showVideoSnapshotUI(boolean enabled) {
+ if (mParameters == null) return;
if (Util.isVideoSnapshotSupported(mParameters) && !mIsVideoCaptureIntent) {
if (ApiHelper.HAS_SURFACE_TEXTURE && enabled) {
((CameraScreenNail) mActivity.mCameraScreenNail).animateCapture(mDisplayRotation);
diff --git a/src/com/android/gallery3d/filtershow/FilterShowActivity.java b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
index f7147eac1..7e8a3f582 100644
--- a/src/com/android/gallery3d/filtershow/FilterShowActivity.java
+++ b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
@@ -71,6 +71,7 @@ import com.android.gallery3d.filtershow.imageshow.ImageZoom;
import com.android.gallery3d.filtershow.imageshow.MasterImage;
import com.android.gallery3d.filtershow.presets.ImagePreset;
import com.android.gallery3d.filtershow.provider.SharedImageProvider;
+import com.android.gallery3d.filtershow.tools.BitmapTask;
import com.android.gallery3d.filtershow.tools.SaveCopyTask;
import com.android.gallery3d.filtershow.ui.FilterIconButton;
import com.android.gallery3d.filtershow.ui.FramedTextButton;
@@ -814,7 +815,6 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
}
public void hideImageViews() {
- mImageShow.setShowControls(false); // reset
for (View view : mImageViews) {
view.setVisibility(View.GONE);
}
@@ -1090,11 +1090,7 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
mCropExtras.getOutputFormat(), this);
}
if (mSaveAsWallpaper) {
- try {
- WallpaperManager.getInstance(this).setBitmap(filtered);
- } catch (IOException e) {
- Log.w(LOGTAG, "fail to set wall paper", e);
- }
+ setWallpaperInBackground(filtered);
}
if (mReturnAsExtra) {
if (filtered != null) {
@@ -1117,6 +1113,28 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
}
}
+ void setWallpaperInBackground(final Bitmap bmap) {
+ Toast.makeText(this, R.string.setting_wallpaper, Toast.LENGTH_LONG).show();
+ BitmapTask.Callbacks<FilterShowActivity> cb = new BitmapTask.Callbacks<FilterShowActivity>() {
+ @Override
+ public void onComplete(Bitmap result) {}
+
+ @Override
+ public void onCancel() {}
+
+ @Override
+ public Bitmap onExecute(FilterShowActivity param) {
+ try {
+ WallpaperManager.getInstance(param).setBitmap(bmap);
+ } catch (IOException e) {
+ Log.w(LOGTAG, "fail to set wall paper", e);
+ }
+ return null;
+ }
+ };
+ (new BitmapTask<FilterShowActivity>(cb)).execute(this);
+ }
+
public void done() {
if (mOutputted) {
hideSavingProgress();
diff --git a/src/com/android/gallery3d/filtershow/PanelController.java b/src/com/android/gallery3d/filtershow/PanelController.java
index 18a9585a6..5bda246da 100644
--- a/src/com/android/gallery3d/filtershow/PanelController.java
+++ b/src/com/android/gallery3d/filtershow/PanelController.java
@@ -375,18 +375,20 @@ public class PanelController implements OnClickListener {
ImageShow image = null;
mActivity.hideImageViews();
for (View view : mImageViews) {
+ image = (ImageShow) view;
if (view.getId() == id) {
view.setVisibility(View.VISIBLE);
- image = (ImageShow) view;
+ image.select();
} else {
view.setVisibility(View.GONE);
+ image.unselect();
}
}
return image;
}
public void showDefaultImageView() {
- showImageView(R.id.imageShow).setShowControls(false);
+ showImageView(R.id.imageShow);
MasterImage.getImage().setCurrentFilter(null);
MasterImage.getImage().setCurrentFilterRepresentation(null);
}
@@ -498,7 +500,7 @@ public class PanelController implements OnClickListener {
}
mUtilityPanel.hideAccessoryViews();
- if (view instanceof FilterIconButton) {
+ if (view instanceof FilterIconButton && view.getId() != R.id.applyEffect) {
mCurrentEditor = null;
FilterIconButton component = (FilterIconButton) view;
FilterRepresentation representation = component.getFilterRepresentation();
@@ -515,7 +517,6 @@ public class PanelController implements OnClickListener {
mCurrentImage = showImageView(representation.getEditorId());
}
}
- mCurrentImage.setShowControls(representation.showEditingControls());
mUtilityPanel.setShowParameter(representation.showParameterValue());
mCurrentImage.select();
@@ -533,7 +534,7 @@ public class PanelController implements OnClickListener {
switch (view.getId()) {
case R.id.tinyplanetButton: {
- mCurrentImage = showImageView(R.id.imageTinyPlanet).setShowControls(true);
+ mCurrentImage = showImageView(R.id.imageTinyPlanet);
String ename = mCurrentImage.getContext().getString(R.string.tinyplanet);
mUtilityPanel.setEffectName(ename);
if (!mDisableFilterButtons) {
@@ -556,8 +557,8 @@ public class PanelController implements OnClickListener {
if (mCurrentImage instanceof ImageCrop && mUtilityPanel.firstTimeCropDisplayed) {
((ImageCrop) mCurrentImage).clear();
mUtilityPanel.firstTimeCropDisplayed = false;
+ ((ImageCrop) mCurrentImage).setFixedAspect(mFixedAspect);
}
- ((ImageCrop) mCurrentImage).setFixedAspect(mFixedAspect);
break;
}
case R.id.rotateButton: {
diff --git a/src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java b/src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java
index 419abe85d..7d5b52921 100644
--- a/src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java
+++ b/src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java
@@ -48,6 +48,7 @@ public class FilteringPipeline implements Handler.Callback {
private final static int NEW_RENDERING_REQUEST = 1;
private final static int COMPUTE_PRESET = 2;
private final static int COMPUTE_RENDERING_REQUEST = 3;
+ private final static int COMPUTE_PARTIAL_RENDERING_REQUEST = 4;
private Handler mProcessingHandler = null;
private final Handler mUIHandler = new Handler() {
@@ -81,7 +82,13 @@ public class FilteringPipeline implements Handler.Callback {
mUIHandler.sendMessage(uimsg);
break;
}
- case COMPUTE_RENDERING_REQUEST: {
+ case COMPUTE_RENDERING_REQUEST:
+ case COMPUTE_PARTIAL_RENDERING_REQUEST: {
+ if (msg.what == COMPUTE_PARTIAL_RENDERING_REQUEST) {
+ if (mProcessingHandler.hasMessages(COMPUTE_PARTIAL_RENDERING_REQUEST)) {
+ return false;
+ }
+ }
RenderingRequest request = (RenderingRequest) msg.obj;
render(request);
Message uimsg = mUIHandler.obtainMessage(NEW_RENDERING_REQUEST);
@@ -95,6 +102,7 @@ public class FilteringPipeline implements Handler.Callback {
private static float RESIZE_FACTOR = 0.8f;
private static float MAX_PROCESS_TIME = 100; // in ms
+ private static long HIRES_DELAY = 100; // in ms
private float mResizeFactor = 1.0f;
private long mResizeTime = 0;
@@ -165,9 +173,17 @@ public class FilteringPipeline implements Handler.Callback {
if (mOriginalAllocation == null) {
return;
}
- Message msg = mProcessingHandler.obtainMessage(COMPUTE_RENDERING_REQUEST);
+ int type = COMPUTE_RENDERING_REQUEST;
+ if (request.getType() == RenderingRequest.PARTIAL_RENDERING) {
+ type = COMPUTE_PARTIAL_RENDERING_REQUEST;
+ }
+ Message msg = mProcessingHandler.obtainMessage(type);
msg.obj = request;
- mProcessingHandler.sendMessage(msg);
+ if (type == COMPUTE_PARTIAL_RENDERING_REQUEST) {
+ mProcessingHandler.sendMessageDelayed(msg, HIRES_DELAY);
+ } else {
+ mProcessingHandler.sendMessage(msg);
+ }
}
public synchronized void updatePreviewBuffer() {
@@ -210,11 +226,15 @@ public class FilteringPipeline implements Handler.Callback {
if (request.getType() == RenderingRequest.GEOMETRY_RENDERING) {
return "GEOMETRY_RENDERING";
}
+ if (request.getType() == RenderingRequest.PARTIAL_RENDERING) {
+ return "PARTIAL_RENDERING";
+ }
return "UNKNOWN TYPE!";
}
private void render(RenderingRequest request) {
- if (request.getBitmap() == null
+ if ((request.getType() != RenderingRequest.PARTIAL_RENDERING
+ && request.getBitmap() == null)
|| request.getImagePreset() == null) {
return;
}
@@ -225,11 +245,21 @@ public class FilteringPipeline implements Handler.Callback {
Bitmap bitmap = request.getBitmap();
ImagePreset preset = request.getImagePreset();
setPresetParameters(preset);
+
+ if (request.getType() == RenderingRequest.PARTIAL_RENDERING) {
+ bitmap = MasterImage.getImage().getImageLoader().getScaleOneImageForPreset(null, preset, request.getBounds(), request.getDestination(), false);
+ if (bitmap == null) {
+ return;
+ }
+ bitmap = preset.applyGeometry(bitmap);
+ }
+
if (request.getType() == RenderingRequest.FILTERS_RENDERING) {
FiltersManager.getManager().resetBitmapsRS();
}
- if (request.getType() != RenderingRequest.ICON_RENDERING) {
+ if (request.getType() != RenderingRequest.ICON_RENDERING
+ && request.getType() != RenderingRequest.PARTIAL_RENDERING) {
updateOriginalAllocation(preset);
}
if (DEBUG) {
@@ -243,9 +273,11 @@ public class FilteringPipeline implements Handler.Callback {
} else if (request.getType() == RenderingRequest.FILTERS_RENDERING) {
mFiltersOnlyOriginalAllocation.copyTo(bitmap);
}
+
if (request.getType() == RenderingRequest.FULL_RENDERING
|| request.getType() == RenderingRequest.FILTERS_RENDERING
- || request.getType() == RenderingRequest.ICON_RENDERING) {
+ || request.getType() == RenderingRequest.ICON_RENDERING
+ || request.getType() == RenderingRequest.PARTIAL_RENDERING) {
Bitmap bmp = preset.apply(bitmap);
request.setBitmap(bmp);
}
diff --git a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java
index 698992ac9..df4f3fd3a 100644
--- a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java
+++ b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java
@@ -91,6 +91,7 @@ public class ImageLoader {
public static final int ORI_TRANSPOSE = ExifInterface.ORIENTATION_TRANSPOSE;
public static final int ORI_TRANSVERSE = ExifInterface.ORIENTATION_TRANSVERSE;
+ private static final int BITMAP_LOAD_BACKOUT_ATTEMPTS = 5;
private Context mContext = null;
private Uri mUri = null;
@@ -264,12 +265,12 @@ public class ImageLoader {
bitmap.getHeight(), matrix, true);
}
- private Bitmap loadRegionBitmap(Uri uri, Rect bounds) {
+ private Bitmap loadRegionBitmap(Uri uri, BitmapFactory.Options options, Rect bounds) {
InputStream is = null;
try {
is = mContext.getContentResolver().openInputStream(uri);
BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(is, false);
- return decoder.decodeRegion(bounds, null);
+ return decoder.decodeRegion(bounds, options);
} catch (FileNotFoundException e) {
Log.e(LOGTAG, "FileNotFoundException: " + uri);
} catch (Exception e) {
@@ -369,11 +370,28 @@ public class ImageLoader {
// FIXME: this currently does the loading + filtering on the UI thread --
// need to move this to a background thread.
public Bitmap getScaleOneImageForPreset(ImageShow caller, ImagePreset imagePreset, Rect bounds,
- boolean force) {
+ Rect destination, boolean force) {
mLoadingLock.lock();
Bitmap bmp = mZoomCache.getImage(imagePreset, bounds);
if (force || bmp == null) {
- bmp = loadRegionBitmap(mUri, bounds);
+ BitmapFactory.Options options = null;
+ if (destination != null) {
+ options = new BitmapFactory.Options();
+ if (bounds.width() > destination.width()) {
+ int sampleSize = 1;
+ int w = bounds.width();
+ while (w > destination.width()) {
+ sampleSize *= 2;
+ w /= sampleSize;
+ }
+ options.inSampleSize = sampleSize;
+ }
+ }
+ bmp = loadRegionBitmap(mUri, options, bounds);
+ if (destination != null) {
+ mLoadingLock.unlock();
+ return bmp;
+ }
if (bmp != null) {
// TODO: this workaround for RS might not be needed ultimately
Bitmap bmp2 = bmp.copy(Bitmap.Config.ARGB_8888, true);
@@ -406,28 +424,97 @@ public class ImageLoader {
public static Bitmap loadMutableBitmap(Context context, Uri sourceUri) {
BitmapFactory.Options options = new BitmapFactory.Options();
+ return loadMutableBitmap(context, sourceUri, options);
+ }
+
+ public static Bitmap loadMutableBitmap(Context context, Uri sourceUri,
+ BitmapFactory.Options options) {
// TODO: on <3.x we need a copy of the bitmap (inMutable doesn't
// exist)
options.inMutable = true;
+ Bitmap bitmap = decodeUriWithBackouts(context, sourceUri, options);
+ if (bitmap == null) {
+ return null;
+ }
+ int orientation = ImageLoader.getOrientation(context, sourceUri);
+ bitmap = ImageLoader.rotateToPortrait(bitmap, orientation);
+ return bitmap;
+ }
+
+ public static Bitmap decodeUriWithBackouts(Context context, Uri sourceUri,
+ BitmapFactory.Options options) {
+ boolean noBitmap = true;
+ int num_tries = 0;
+ InputStream is = getInputStream(context, sourceUri);
+
+ if (options.inSampleSize < 1) {
+ options.inSampleSize = 1;
+ }
+ // Stopgap fix for low-memory devices.
+ Bitmap bmap = null;
+ while (noBitmap) {
+ if (is == null) {
+ return null;
+ }
+ try {
+ // Try to decode, downsample if low-memory.
+ bmap = BitmapFactory.decodeStream(is, null, options);
+ noBitmap = false;
+ } catch (java.lang.OutOfMemoryError e) {
+ // Try 5 times before failing for good.
+ if (++num_tries >= BITMAP_LOAD_BACKOUT_ATTEMPTS) {
+ throw e;
+ }
+ is = null;
+ bmap = null;
+ System.gc();
+ is = getInputStream(context, sourceUri);
+ options.inSampleSize *= 2;
+ }
+ }
+ Utils.closeSilently(is);
+ return bmap;
+ }
+
+ private static InputStream getInputStream(Context context, Uri sourceUri) {
InputStream is = null;
- Bitmap bitmap = null;
try {
is = context.getContentResolver().openInputStream(sourceUri);
- bitmap = BitmapFactory.decodeStream(is, null, options);
} catch (FileNotFoundException e) {
Log.w(LOGTAG, "could not load bitmap ", e);
- is = null;
- bitmap = null;
- } finally {
Utils.closeSilently(is);
+ is = null;
}
- if (bitmap == null) {
- return null;
+ return is;
+ }
+
+ public static Bitmap decodeResourceWithBackouts(Resources res, BitmapFactory.Options options,
+ int id) {
+ boolean noBitmap = true;
+ int num_tries = 0;
+ if (options.inSampleSize < 1) {
+ options.inSampleSize = 1;
}
- int orientation = ImageLoader.getOrientation(context, sourceUri);
- bitmap = ImageLoader.rotateToPortrait(bitmap, orientation);
- return bitmap;
+ // Stopgap fix for low-memory devices.
+ Bitmap bmap = null;
+ while (noBitmap) {
+ try {
+ // Try to decode, downsample if low-memory.
+ bmap = BitmapFactory.decodeResource(
+ res, id, options);
+ noBitmap = false;
+ } catch (java.lang.OutOfMemoryError e) {
+ // Try 5 times before failing for good.
+ if (++num_tries >= BITMAP_LOAD_BACKOUT_ATTEMPTS) {
+ throw e;
+ }
+ bmap = null;
+ System.gc();
+ options.inSampleSize *= 2;
+ }
+ }
+ return bmap;
}
public void returnFilteredResult(ImagePreset preset,
@@ -451,13 +538,36 @@ public class ImageLoader {
if (param == null || mUri == null) {
return null;
}
- Bitmap bitmap = loadMutableBitmap(mContext, mUri);
- if (bitmap == null) {
- Log.w(LOGTAG, "Failed to save image!");
- return null;
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ boolean noBitmap = true;
+ int num_tries = 0;
+ if (options.inSampleSize < 1) {
+ options.inSampleSize = 1;
}
- bitmap = param.applyGeometry(bitmap);
- return param.apply(bitmap);
+ Bitmap bitmap = null;
+ // Stopgap fix for low-memory devices.
+ while (noBitmap) {
+ try {
+ // Try to do bitmap operations, downsample if low-memory
+ bitmap = loadMutableBitmap(mContext, mUri, options);
+ if (bitmap == null) {
+ Log.w(LOGTAG, "Failed to save image!");
+ return null;
+ }
+ bitmap = param.applyGeometry(bitmap);
+ bitmap = param.apply(bitmap);
+ noBitmap = false;
+ } catch (java.lang.OutOfMemoryError e) {
+ // Try 5 times before failing for good.
+ if (++num_tries >= 5) {
+ throw e;
+ }
+ bitmap = null;
+ System.gc();
+ options.inSampleSize *= 2;
+ }
+ }
+ return bitmap;
}
};
diff --git a/src/com/android/gallery3d/filtershow/cache/RenderingRequest.java b/src/com/android/gallery3d/filtershow/cache/RenderingRequest.java
index 1e9f6b83a..3ec74e266 100644
--- a/src/com/android/gallery3d/filtershow/cache/RenderingRequest.java
+++ b/src/com/android/gallery3d/filtershow/cache/RenderingRequest.java
@@ -17,6 +17,7 @@
package com.android.gallery3d.filtershow.cache;
import android.graphics.Bitmap;
+import android.graphics.Rect;
import com.android.gallery3d.app.Log;
import com.android.gallery3d.filtershow.imageshow.MasterImage;
import com.android.gallery3d.filtershow.presets.ImagePreset;
@@ -27,29 +28,46 @@ public class RenderingRequest {
private Bitmap mBitmap = null;
private ImagePreset mImagePreset = null;
private RenderingRequestCaller mCaller = null;
+ private Rect mBounds = null;
+ private Rect mDestination = null;
private int mType = FULL_RENDERING;
- public static int FULL_RENDERING = 0;
- public static int FILTERS_RENDERING = 1;
- public static int GEOMETRY_RENDERING = 2;
- public static int ICON_RENDERING = 3;
+ public static final int FULL_RENDERING = 0;
+ public static final int FILTERS_RENDERING = 1;
+ public static final int GEOMETRY_RENDERING = 2;
+ public static final int ICON_RENDERING = 3;
+ public static final int PARTIAL_RENDERING = 4;
private static final Bitmap.Config mConfig = Bitmap.Config.ARGB_8888;
+ public static void post(Bitmap source, ImagePreset preset, int type, RenderingRequestCaller caller) {
+ RenderingRequest.post(source, preset, type, caller, null, null);
+ }
+
public static void post(Bitmap source, ImagePreset preset, int type,
- RenderingRequestCaller caller) {
- if (source == null || preset == null || caller == null) {
+ RenderingRequestCaller caller, Rect bounds, Rect destination) {
+ if ((type != PARTIAL_RENDERING && source == null) || preset == null || caller == null) {
Log.v(LOGTAG, "something null: source: " + source + " or preset: " + preset + " or caller: " + caller);
return;
}
RenderingRequest request = new RenderingRequest();
Bitmap bitmap = null;
- if (type == FULL_RENDERING || type == GEOMETRY_RENDERING || type == ICON_RENDERING) {
+ if (type == FULL_RENDERING
+ || type == GEOMETRY_RENDERING
+ || type == ICON_RENDERING) {
bitmap = preset.applyGeometry(source);
- } else {
+ } else if (type != PARTIAL_RENDERING) {
bitmap = Bitmap.createBitmap(source.getWidth(), source.getHeight(), mConfig);
}
+
request.setBitmap(bitmap);
ImagePreset passedPreset = new ImagePreset(preset);
passedPreset.setImageLoader(MasterImage.getImage().getImageLoader());
+
+ if (type == PARTIAL_RENDERING) {
+ request.setBounds(bounds);
+ request.setDestination(destination);
+ passedPreset.setPartialRendering(true, bounds);
+ }
+
request.setImagePreset(passedPreset);
request.setType(type);
request.setCaller(caller);
@@ -103,4 +121,20 @@ public class RenderingRequest {
public void setCaller(RenderingRequestCaller caller) {
mCaller = caller;
}
+
+ public Rect getBounds() {
+ return mBounds;
+ }
+
+ public void setBounds(Rect bounds) {
+ mBounds = bounds;
+ }
+
+ public Rect getDestination() {
+ return mDestination;
+ }
+
+ public void setDestination(Rect destination) {
+ mDestination = destination;
+ }
}
diff --git a/src/com/android/gallery3d/filtershow/editors/EditorVignette.java b/src/com/android/gallery3d/filtershow/editors/EditorVignette.java
new file mode 100644
index 000000000..a60c1681e
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/editors/EditorVignette.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.android.gallery3d.filtershow.editors;
+
+import android.content.Context;
+import android.util.Log;
+import android.widget.FrameLayout;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.filters.FilterRepresentation;
+import com.android.gallery3d.filtershow.filters.FilterTinyPlanetRepresentation;
+import com.android.gallery3d.filtershow.filters.FilterVignetteRepresentation;
+import com.android.gallery3d.filtershow.imageshow.ImageVignette;
+
+public class EditorVignette extends BasicEditor {
+ public static final int ID = R.id.vignetteEditor;
+ private static final String LOGTAG = "EditorVignettePlanet";
+ ImageVignette mImageVignette;
+
+ public EditorVignette() {
+ super(ID, R.layout.filtershow_vignette_editor, R.id.imageVignette);
+ }
+
+ @Override
+ public void createEditor(Context context, FrameLayout frameLayout) {
+ super.createEditor(context, frameLayout);
+ mImageVignette = (ImageVignette) mImageShow;
+ mImageVignette.setEditor(this);
+ }
+
+ @Override
+ public void reflectCurrentFilter() {
+ super.reflectCurrentFilter();
+
+ FilterRepresentation rep = getLocalRepresentation();
+ if (rep != null && getLocalRepresentation() instanceof FilterVignetteRepresentation) {
+ FilterVignetteRepresentation drawRep = (FilterVignetteRepresentation) rep;
+ mImageVignette.setRepresentation(drawRep);
+ }
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java b/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java
index 43660d6a0..377bd2b6f 100644
--- a/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java
+++ b/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java
@@ -42,6 +42,7 @@ public class BaseFiltersManager {
filters.add(new ImageFilterVignette());
filters.add(new ImageFilterContrast());
filters.add(new ImageFilterShadows());
+ filters.add(new ImageFilterHighlights());
filters.add(new ImageFilterVibrance());
filters.add(new ImageFilterSharpen());
filters.add(new ImageFilterCurves());
@@ -89,6 +90,7 @@ public class BaseFiltersManager {
representations.add(getRepresentation(ImageFilterVignette.class));
representations.add(getRepresentation(ImageFilterContrast.class));
representations.add(getRepresentation(ImageFilterShadows.class));
+ representations.add(getRepresentation(ImageFilterHighlights.class));
representations.add(getRepresentation(ImageFilterVibrance.class));
representations.add(getRepresentation(ImageFilterSharpen.class));
representations.add(getRepresentation(ImageFilterCurves.class));
diff --git a/src/com/android/gallery3d/filtershow/filters/FilterCurvesRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterCurvesRepresentation.java
index 6c831708e..3511c67af 100644
--- a/src/com/android/gallery3d/filtershow/filters/FilterCurvesRepresentation.java
+++ b/src/com/android/gallery3d/filtershow/filters/FilterCurvesRepresentation.java
@@ -19,6 +19,7 @@ public class FilterCurvesRepresentation extends FilterRepresentation {
setShowEditingControls(false);
setShowParameterValue(false);
setShowUtilityPanel(true);
+ setSupportsPartialRendering(true);
for (int i = 0; i < mSplines.length; i++) {
mSplines[i] = new Spline();
mSplines[i].reset();
diff --git a/src/com/android/gallery3d/filtershow/filters/FilterDrawRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterDrawRepresentation.java
index e41f0a622..8b8504bbc 100644
--- a/src/com/android/gallery3d/filtershow/filters/FilterDrawRepresentation.java
+++ b/src/com/android/gallery3d/filtershow/filters/FilterDrawRepresentation.java
@@ -150,6 +150,10 @@ public class FilterDrawRepresentation extends FilterRepresentation {
mCurrent = null;
}
+ public void clearCurrentSection() {
+ mCurrent = null;
+ }
+
public void clear() {
mCurrent = null;
mDrawing.clear();
diff --git a/src/com/android/gallery3d/filtershow/filters/FilterFxRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterFxRepresentation.java
index 859bf327c..d4128dc79 100644
--- a/src/com/android/gallery3d/filtershow/filters/FilterFxRepresentation.java
+++ b/src/com/android/gallery3d/filtershow/filters/FilterFxRepresentation.java
@@ -37,6 +37,7 @@ public class FilterFxRepresentation extends FilterRepresentation {
setShowEditingControls(false);
setShowParameterValue(false);
setShowUtilityPanel(false);
+ setSupportsPartialRendering(true);
}
public String toString() {
diff --git a/src/com/android/gallery3d/filtershow/filters/FilterRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterRepresentation.java
index 513cdcdef..83f2a1b87 100644
--- a/src/com/android/gallery3d/filtershow/filters/FilterRepresentation.java
+++ b/src/com/android/gallery3d/filtershow/filters/FilterRepresentation.java
@@ -25,6 +25,7 @@ public class FilterRepresentation implements Cloneable {
private String mName;
private int mPriority = TYPE_NORMAL;
private Class mFilterClass;
+ private boolean mSupportsPartialRendering = false;
private int mTextId = 0;
private int mEditorId = BasicEditor.ID;
private int mButtonId = 0;
@@ -52,6 +53,7 @@ public class FilterRepresentation implements Cloneable {
representation.setName(getName());
representation.setPriority(getPriority());
representation.setFilterClass(getFilterClass());
+ representation.setSupportsPartialRendering(supportsPartialRendering());
representation.setTextId(getTextId());
representation.setEditorId(getEditorId());
representation.setButtonId(getButtonId());
@@ -70,6 +72,7 @@ public class FilterRepresentation implements Cloneable {
if (representation.mFilterClass == representation.mFilterClass
&& representation.mName.equalsIgnoreCase(mName)
&& representation.mPriority == mPriority
+ && representation.mSupportsPartialRendering == mSupportsPartialRendering
&& representation.mTextId == mTextId
&& representation.mEditorId == mEditorId
&& representation.mButtonId == mButtonId
@@ -106,6 +109,14 @@ public class FilterRepresentation implements Cloneable {
return false;
}
+ public boolean supportsPartialRendering() {
+ return mSupportsPartialRendering;
+ }
+
+ public void setSupportsPartialRendering(boolean value) {
+ mSupportsPartialRendering = value;
+ }
+
public void useParametersFrom(FilterRepresentation a) {
}
diff --git a/src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java
new file mode 100644
index 000000000..eef54ef58
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.android.gallery3d.filtershow.filters;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.editors.EditorVignette;
+import com.android.gallery3d.filtershow.imageshow.Oval;
+
+public class FilterVignetteRepresentation extends FilterBasicRepresentation implements Oval {
+ private static final String LOGTAG = "FilterVignetteRepresentation";
+ private float mCenterX = Float.NaN;
+ private float mCenterY;
+ private float mRadiusX = Float.NaN;
+ private float mRadiusY;
+
+ public FilterVignetteRepresentation() {
+ super("Vignette", -100, 50, 100);
+ setShowParameterValue(true);
+ setPriority(FilterRepresentation.TYPE_VIGNETTE);
+ setTextId(R.string.vignette);
+ setButtonId(R.id.vignetteEditor);
+ 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;
+ }
+
+ @Override
+ public FilterRepresentation clone() throws CloneNotSupportedException {
+ FilterVignetteRepresentation representation = (FilterVignetteRepresentation) super
+ .clone();
+ representation.mCenterX = mCenterX;
+ representation.mCenterY = mCenterY;
+
+ return representation;
+ }
+
+ @Override
+ public void setCenter(float centerX, float centerY) {
+ mCenterX = centerX;
+ mCenterY = centerY;
+ }
+
+ @Override
+ public float getCenterX() {
+ return mCenterX;
+ }
+
+ @Override
+ public float getCenterY() {
+ return mCenterY;
+ }
+
+ @Override
+ public void setRadius(float radiusX, float radiusY) {
+ mRadiusX = radiusX;
+ mRadiusY = radiusY;
+ }
+
+ @Override
+ public void setRadiusX(float radiusX) {
+ mRadiusX = radiusX;
+ }
+
+ @Override
+ public void setRadiusY(float radiusY) {
+ mRadiusY = radiusY;
+ }
+
+ @Override
+ public float getRadiusX() {
+ return mRadiusX;
+ }
+
+ @Override
+ public float getRadiusY() {
+ return mRadiusY;
+ }
+
+ public boolean isCenterSet() {
+ return mCenterX != Float.NaN;
+ }
+
+ @Override
+ public boolean isNil() {
+ return getValue() == 0;
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterBwFilter.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterBwFilter.java
index c92ac012d..a4626cdb2 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterBwFilter.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterBwFilter.java
@@ -36,6 +36,7 @@ public class ImageFilterBwFilter extends SimpleImageFilter {
representation.setMinimum(-180);
representation.setTextId(R.string.bwfilter);
representation.setButtonId(R.id.bwfilterButton);
+ representation.setSupportsPartialRendering(true);
return representation;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java
index 2f94e3d17..2097f0d6e 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java
@@ -37,6 +37,7 @@ public class ImageFilterContrast extends SimpleImageFilter {
representation.setMinimum(-100);
representation.setMaximum(100);
representation.setDefaultValue(0);
+ representation.setSupportsPartialRendering(true);
return representation;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterEdge.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterEdge.java
index 55c709573..46a9a294c 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterEdge.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterEdge.java
@@ -32,6 +32,7 @@ public class ImageFilterEdge extends SimpleImageFilter {
representation.setFilterClass(ImageFilterEdge.class);
representation.setTextId(R.string.edge);
representation.setButtonId(R.id.edgeButton);
+ representation.setSupportsPartialRendering(true);
return representation;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterExposure.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterExposure.java
index 7a8df71af..b0b0b2dd8 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterExposure.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterExposure.java
@@ -36,6 +36,7 @@ public class ImageFilterExposure extends SimpleImageFilter {
representation.setMinimum(-100);
representation.setMaximum(100);
representation.setDefaultValue(0);
+ representation.setSupportsPartialRendering(true);
return representation;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterHighlights.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterHighlights.java
new file mode 100644
index 000000000..12f032dcd
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterHighlights.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.android.gallery3d.filtershow.filters;
+
+import com.android.gallery3d.R;
+
+import android.graphics.Bitmap;
+import android.util.Log;
+
+public class ImageFilterHighlights extends SimpleImageFilter {
+ private static final String LOGTAG = "ImageFilterVignette";
+
+ public ImageFilterHighlights() {
+ mName = "Highlights";
+ }
+
+ SplineMath mSpline = new SplineMath(5);
+ double[] mHighlightCurve = { 0.0, 0.32, 0.418, 0.476, 0.642 };
+
+ public FilterRepresentation getDefaultRepresentation() {
+ FilterBasicRepresentation representation =
+ (FilterBasicRepresentation) super.getDefaultRepresentation();
+ representation.setName("Shadows");
+ representation.setFilterClass(ImageFilterHighlights.class);
+ representation.setTextId(R.string.highlight_recovery);
+ representation.setButtonId(R.id.highlightRecoveryButton);
+ representation.setMinimum(-100);
+ representation.setMaximum(100);
+ representation.setDefaultValue(0);
+ representation.setSupportsPartialRendering(true);
+ return representation;
+ }
+
+ native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float[] luminanceMap);
+
+ @Override
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
+ if (getParameters() == null) {
+ return bitmap;
+ }
+ float p = getParameters().getValue();
+ double t = p/100.;
+ for (int i = 0; i < 5; i++) {
+ double x = i / 4.;
+ double y = mHighlightCurve[i] *t+x*(1-t);
+ mSpline.setPoint(i, x, y);
+ }
+
+ float[][] curve = mSpline.calculatetCurve(256);
+ float[] luminanceMap = new float[curve.length];
+ for (int i = 0; i < luminanceMap.length; i++) {
+ luminanceMap[i] = curve[i][1];
+ }
+ int w = bitmap.getWidth();
+ int h = bitmap.getHeight();
+
+ nativeApplyFilter(bitmap, w, h, luminanceMap);
+ return bitmap;
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java
index 8c484c72e..b1f9f7365 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java
@@ -39,6 +39,7 @@ public class ImageFilterHue extends SimpleImageFilter {
representation.setTextId(R.string.hue);
representation.setButtonId(R.id.hueButton);
representation.setEditorId(BasicEditor.ID);
+ representation.setSupportsPartialRendering(true);
return representation;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterKMeans.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterKMeans.java
index f48bd047a..6f785ef54 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterKMeans.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterKMeans.java
@@ -45,6 +45,7 @@ public class ImageFilterKMeans extends SimpleImageFilter {
representation.setPreviewValue(4);
representation.setTextId(R.string.kmeans);
representation.setButtonId(R.id.kmeansButton);
+ representation.setSupportsPartialRendering(true);
return representation;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterNegative.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterNegative.java
index 841c5c913..c256686fb 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterNegative.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterNegative.java
@@ -19,6 +19,7 @@ public class ImageFilterNegative extends ImageFilter {
representation.setShowEditingControls(false);
representation.setShowParameterValue(false);
representation.setEditorId(ImageOnlyEditor.ID);
+ representation.setSupportsPartialRendering(true);
return representation;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
index d5297904d..74712be47 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
@@ -43,9 +43,11 @@ public abstract class ImageFilterRS extends ImageFilter {
|| (bitmap.getHeight() != sOldBitmap.getHeight())) {
if (mInPixelsAllocation != null) {
mInPixelsAllocation.destroy();
+ mInPixelsAllocation = null;
}
if (mOutPixelsAllocation != null) {
mOutPixelsAllocation.destroy();
+ mOutPixelsAllocation = null;
}
Bitmap bitmapBuffer = bitmap.copy(mBitmapConfig, true);
mOutPixelsAllocation = Allocation.createFromBitmap(mRS, bitmapBuffer,
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java
index 6cd833206..0febe4957 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java
@@ -37,6 +37,7 @@ public class ImageFilterSaturated extends SimpleImageFilter {
representation.setMinimum(-100);
representation.setMaximum(100);
representation.setDefaultValue(0);
+ representation.setSupportsPartialRendering(true);
return representation;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java
index e17823955..fd67ee8fc 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java
@@ -37,6 +37,7 @@ public class ImageFilterShadows extends SimpleImageFilter {
representation.setMinimum(-100);
representation.setMaximum(100);
representation.setDefaultValue(0);
+ representation.setSupportsPartialRendering(true);
return representation;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterSharpen.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterSharpen.java
index 9c99d57d0..8afa47451 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterSharpen.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterSharpen.java
@@ -37,7 +37,8 @@ public class ImageFilterSharpen extends ImageFilterRS {
representation.setTextId(R.string.sharpness);
representation.setButtonId(R.id.sharpenButton);
representation.setOverlayId(R.drawable.filtershow_button_colors_sharpen);
- representation.setEditorId(R.id.imageZoom);
+ representation.setEditorId(R.id.imageShow);
+ representation.setSupportsPartialRendering(true);
return representation;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterVibrance.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterVibrance.java
index a57af71df..ea315d326 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterVibrance.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterVibrance.java
@@ -36,6 +36,7 @@ public class ImageFilterVibrance extends SimpleImageFilter {
representation.setMinimum(-100);
representation.setMaximum(100);
representation.setDefaultValue(0);
+ representation.setSupportsPartialRendering(true);
return representation;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java
index 465d90bfd..9ff737e32 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java
@@ -16,47 +16,67 @@
package com.android.gallery3d.filtershow.filters;
-import com.android.gallery3d.R;
-
import android.graphics.Bitmap;
+import android.graphics.Matrix;
+
import com.android.gallery3d.app.Log;
public class ImageFilterVignette extends SimpleImageFilter {
-
private static final String LOGTAG = "ImageFilterVignette";
public ImageFilterVignette() {
mName = "Vignette";
}
+ @Override
public FilterRepresentation getDefaultRepresentation() {
- FilterBasicRepresentation representation =
- (FilterBasicRepresentation) super.getDefaultRepresentation();
- representation.setName("Vignette");
- representation.setFilterClass(ImageFilterVignette.class);
- representation.setPriority(FilterRepresentation.TYPE_VIGNETTE);
- representation.setTextId(R.string.vignette);
- representation.setButtonId(R.id.vignetteButton);
-
- representation.setMinimum(-100);
- representation.setMaximum(100);
- representation.setDefaultValue(0);
-
+ FilterVignetteRepresentation representation = new FilterVignetteRepresentation();
return representation;
}
- native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float strength);
+ native protected void nativeApplyFilter(
+ Bitmap bitmap, int w, int h, int cx, int cy, float radx, float rady, float strength);
+
+ private float calcRadius(float cx, float cy, int w, int h) {
+ float d = cx;
+ if (d < (w - cx)) {
+ d = w - cx;
+ }
+ if (d < cy) {
+ d = cy;
+ }
+ if (d < (h - cy)) {
+ d = h - cy;
+ }
+ return d * d * 2.0f;
+ }
@Override
public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
- if (getParameters() == null) {
+ FilterVignetteRepresentation rep = (FilterVignetteRepresentation) getParameters();
+ if (rep == null) {
return bitmap;
}
int w = bitmap.getWidth();
int h = bitmap.getHeight();
- float value = getParameters().getValue() / 100.0f;
- nativeApplyFilter(bitmap, w, h, value);
-
+ 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);
return bitmap;
}
}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterWBalance.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterWBalance.java
index 2f4852306..c4c293a4b 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterWBalance.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterWBalance.java
@@ -37,6 +37,7 @@ public class ImageFilterWBalance extends ImageFilter {
representation.setShowEditingControls(false);
representation.setShowParameterValue(false);
representation.setEditorId(ImageOnlyEditor.ID);
+ representation.setSupportsPartialRendering(true);
return representation;
}
diff --git a/src/com/android/gallery3d/filtershow/filters/SplineMath.java b/src/com/android/gallery3d/filtershow/filters/SplineMath.java
new file mode 100644
index 000000000..5b12d0a61
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/filters/SplineMath.java
@@ -0,0 +1,166 @@
+package com.android.gallery3d.filtershow.filters;
+
+
+public class SplineMath {
+ double[][] mPoints = new double[6][2];
+ double[] mDerivatives;
+ SplineMath(int n) {
+ mPoints = new double[n][2];
+ }
+
+ public void setPoint(int index, double x, double y) {
+ mPoints[index][0] = x;
+ mPoints[index][1] = y;
+ mDerivatives = null;
+ }
+
+ public float[][] calculatetCurve(int n) {
+ float[][] curve = new float[n][2];
+ double[][] points = new double[mPoints.length][2];
+ for (int i = 0; i < mPoints.length; i++) {
+
+ points[i][0] = mPoints[i][0];
+ points[i][1] = mPoints[i][1];
+
+ }
+ double[] derivatives = solveSystem(points);
+ float start = (float) points[0][0];
+ float end = (float) (points[points.length - 1][0]);
+
+ curve[0][0] = (float) (points[0][0]);
+ curve[0][1] = (float) (points[0][1]);
+ int last = curve.length - 1;
+ curve[last][0] = (float) (points[points.length - 1][0]);
+ curve[last][1] = (float) (points[points.length - 1][1]);
+
+ for (int i = 0; i < curve.length; i++) {
+
+ double[] cur = null;
+ double[] next = null;
+ double x = start + i * (end - start) / (curve.length - 1);
+ int pivot = 0;
+ for (int j = 0; j < points.length - 1; j++) {
+ if (x >= points[j][0] && x <= points[j + 1][0]) {
+ pivot = j;
+ }
+ }
+ cur = points[pivot];
+ next = points[pivot + 1];
+ if (x <= next[0]) {
+ double x1 = cur[0];
+ double x2 = next[0];
+ double y1 = cur[1];
+ double y2 = next[1];
+
+ // Use the second derivatives to apply the cubic spline
+ // equation:
+ double delta = (x2 - x1);
+ double delta2 = delta * delta;
+ double b = (x - x1) / delta;
+ double a = 1 - b;
+ double ta = a * y1;
+ double tb = b * y2;
+ double tc = (a * a * a - a) * derivatives[pivot];
+ double td = (b * b * b - b) * derivatives[pivot + 1];
+ double y = ta + tb + (delta2 / 6) * (tc + td);
+
+ curve[i][0] = (float) (x);
+ curve[i][1] = (float) (y);
+ } else {
+ curve[i][0] = (float) (next[0]);
+ curve[i][1] = (float) (next[1]);
+ }
+ }
+ return curve;
+ }
+
+ public double getValue(double x) {
+ double[] cur = null;
+ double[] next = null;
+ if (mDerivatives == null)
+ mDerivatives = solveSystem(mPoints);
+ int pivot = 0;
+ for (int j = 0; j < mPoints.length - 1; j++) {
+ pivot = j;
+ if (x <= mPoints[j][0]) {
+ break;
+ }
+ }
+ cur = mPoints[pivot];
+ next = mPoints[pivot + 1];
+ double x1 = cur[0];
+ double x2 = next[0];
+ double y1 = cur[1];
+ double y2 = next[1];
+
+ // Use the second derivatives to apply the cubic spline
+ // equation:
+ double delta = (x2 - x1);
+ double delta2 = delta * delta;
+ double b = (x - x1) / delta;
+ double a = 1 - b;
+ double ta = a * y1;
+ double tb = b * y2;
+ double tc = (a * a * a - a) * mDerivatives[pivot];
+ double td = (b * b * b - b) * mDerivatives[pivot + 1];
+ double y = ta + tb + (delta2 / 6) * (tc + td);
+
+ return y;
+
+ }
+
+ double[] solveSystem(double[][] points) {
+ int n = points.length;
+ double[][] system = new double[n][3];
+ double[] result = new double[n]; // d
+ double[] solution = new double[n]; // returned coefficients
+ system[0][1] = 1;
+ system[n - 1][1] = 1;
+ double d6 = 1.0 / 6.0;
+ double d3 = 1.0 / 3.0;
+
+ // let's create a tridiagonal matrix representing the
+ // system, and apply the TDMA algorithm to solve it
+ // (see http://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm)
+ for (int i = 1; i < n - 1; i++) {
+ double deltaPrevX = points[i][0] - points[i - 1][0];
+ double deltaX = points[i + 1][0] - points[i - 1][0];
+ double deltaNextX = points[i + 1][0] - points[i][0];
+ double deltaNextY = points[i + 1][1] - points[i][1];
+ double deltaPrevY = points[i][1] - points[i - 1][1];
+ system[i][0] = d6 * deltaPrevX; // a_i
+ system[i][1] = d3 * deltaX; // b_i
+ system[i][2] = d6 * deltaNextX; // c_i
+ result[i] = (deltaNextY / deltaNextX) - (deltaPrevY / deltaPrevX); // d_i
+ }
+
+ // Forward sweep
+ for (int i = 1; i < n; i++) {
+ // m = a_i/b_i-1
+ double m = system[i][0] / system[i - 1][1];
+ // b_i = b_i - m(c_i-1)
+ system[i][1] = system[i][1] - m * system[i - 1][2];
+ // d_i = d_i - m(d_i-1)
+ result[i] = result[i] - m * result[i - 1];
+ }
+
+ // Back substitution
+ solution[n - 1] = result[n - 1] / system[n - 1][1];
+ for (int i = n - 2; i >= 0; --i) {
+ solution[i] = (result[i] - system[i][2] * solution[i + 1]) / system[i][1];
+ }
+ return solution;
+ }
+
+ public static void main(String[] args) {
+ SplineMath s = new SplineMath(10);
+ for (int i = 0; i < 10; i++) {
+ s.setPoint(i, i, i);
+ }
+ float[][] curve = s.calculatetCurve(40);
+
+ for (int j = 0; j < curve.length; j++) {
+ System.out.println(curve[j][0] + "," + curve[j][1]);
+ }
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java b/src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java
new file mode 100644
index 000000000..b4ca8e1f1
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.android.gallery3d.filtershow.imageshow;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.RectF;
+import android.graphics.Shader;
+
+import com.android.gallery3d.R;
+
+public class EclipseControl {
+ private float mCenterX = Float.NaN;
+ private float mCenterY = 0;
+ private float mRadiusX = 200;
+ private float mRadiusY = 300;
+ private static int MIN_TOUCH_DIST = 80;// should be a resource & in dips
+
+ private float[] handlex = new float[9];
+ private float[] handley = new float[9];
+ private int mSliderColor;
+ private int mCenterDotSize = 40;
+ private float mDownX;
+ private float mDownY;
+ private float mDownCenterX;
+ private float mDownCenterY;
+ private float mDownRadiusX;
+ private float mDownRadiusY;
+ private Matrix mScrToImg;
+
+ private final static int HAN_CENTER = 0;
+ private final static int HAN_NORTH = 7;
+ private final static int HAN_NE = 8;
+ private final static int HAN_EAST = 1;
+ private final static int HAN_SE = 2;
+ private final static int HAN_SOUTH = 3;
+ private final static int HAN_SW = 4;
+ private final static int HAN_WEST = 5;
+ private final static int HAN_NW = 6;
+
+ public EclipseControl(Context context) {
+ mSliderColor = context.getResources().getColor(R.color.slider_line_color);
+ }
+
+ public void setRadius(float x, float y) {
+ mRadiusX = x;
+ mRadiusY = y;
+ }
+
+ public void setCenter(float x, float y) {
+ mCenterX = x;
+ mCenterY = y;
+ }
+
+ public int getCloseHandle(float x, float y) {
+ float min = Float.MAX_VALUE;
+ int handle = -1;
+ for (int i = 0; i < handlex.length; i++) {
+ float dx = handlex[i] - x;
+ float dy = handley[i] - y;
+ float dist = dx * dx + dy * dy;
+ if (dist < min) {
+ min = dist;
+ handle = i;
+ }
+ }
+
+ if (min < MIN_TOUCH_DIST * MIN_TOUCH_DIST) {
+ return handle;
+ }
+ for (int i = 0; i < handlex.length; i++) {
+ float dx = handlex[i] - x;
+ float dy = handley[i] - y;
+ float dist = (float) Math.sqrt(dx * dx + dy * dy);
+ }
+
+ return -1;
+ }
+
+ public void setScrToImageMatrix(Matrix scrToImg) {
+ mScrToImg = scrToImg;
+ }
+
+ public void actionDown(float x, float y, Oval oval) {
+ float[] point = new float[] {
+ x, y };
+ mScrToImg.mapPoints(point);
+ mDownX = point[0];
+ mDownY = point[1];
+ mDownCenterX = oval.getCenterX();
+ mDownCenterY = oval.getCenterY();
+ mDownRadiusX = oval.getRadiusX();
+ mDownRadiusY = oval.getRadiusY();
+ }
+
+ public void actionMove(int handle, float x, float y, Oval oval) {
+ float[] point = new float[] {
+ x, y };
+ mScrToImg.mapPoints(point);
+ x = point[0];
+ y = point[1];
+ int sign = 1;
+ switch (handle) {
+ case HAN_CENTER:
+ float ctrdx = mDownX - mDownCenterX;
+ float ctrdy = mDownY - mDownCenterY;
+ oval.setCenter(x - ctrdx, y - ctrdy);
+ // setRepresentation(mVignetteRep);
+ break;
+ case HAN_NORTH:
+ sign = -1;
+ case HAN_SOUTH:
+ float raddy = mDownRadiusY - Math.abs(mDownY - mDownCenterY);
+ oval.setRadiusY(Math.abs(y - oval.getCenterY() + sign * raddy));
+ break;
+ case HAN_EAST:
+ sign = -1;
+ case HAN_WEST:
+ float raddx = mDownRadiusX - Math.abs(mDownX - mDownCenterX);
+ oval.setRadiusX(Math.abs(x - oval.getCenterX() - sign * raddx));
+ break;
+ case HAN_SE:
+ case HAN_NE:
+ case HAN_SW:
+ case HAN_NW:
+ float sin45 = (float) Math.sin(45);
+ float dr = (mDownRadiusX + mDownRadiusY) * sin45;
+ float ctr_dx = mDownX - mDownCenterX;
+ float ctr_dy = mDownY - mDownCenterY;
+ float downRad = Math.abs(ctr_dx) + Math.abs(ctr_dy) - dr;
+ float rx = oval.getRadiusX();
+ float ry = oval.getRadiusY();
+ float r = (Math.abs(rx) + Math.abs(ry)) * sin45;
+ float dx = x - oval.getCenterX();
+ float dy = y - oval.getCenterY();
+ float nr = Math.abs(Math.abs(dx) + Math.abs(dy) - downRad);
+ oval.setRadius(rx * nr / r, ry * nr / r);
+
+ break;
+ }
+ }
+
+ void paintPoint(Canvas canvas, float x, float y) {
+ if (x == Float.NaN) {
+ return;
+ }
+
+ Paint paint = new Paint();
+
+ paint.setStyle(Paint.Style.FILL);
+ paint.setColor(Color.BLUE);
+ int[] colors3 = new int[] {
+ mSliderColor, mSliderColor, 0x66000000, 0 };
+ RadialGradient g = new RadialGradient(x, y, mCenterDotSize, colors3, new float[] {
+ 0, .3f, .31f, 1 }, Shader.TileMode.CLAMP);
+ paint.setShader(g);
+ canvas.drawCircle(x, y, mCenterDotSize, paint);
+ }
+
+ void paintRadius(Canvas canvas, float cx, float cy, float rx, float ry) {
+ if (cx == Float.NaN) {
+ return;
+ }
+ int mSliderColor = 0xFF33B5E5;
+ Paint paint = new Paint();
+ RectF rect = new RectF(cx - rx, cy - ry, cx + rx, cy + ry);
+ paint.setAntiAlias(true);
+ paint.setStyle(Paint.Style.STROKE);
+ paint.setStrokeWidth(6);
+ paint.setColor(Color.BLACK);
+ paintOvallines(canvas, rect, paint, cx, cy, rx, ry);
+
+ paint.setStrokeWidth(3);
+ paint.setColor(Color.WHITE);
+ paintOvallines(canvas, rect, paint, cx, cy, rx, ry);
+ }
+
+ public void paintOvallines(
+ Canvas canvas, RectF rect, Paint paint, float cx, float cy, float rx, float ry) {
+ canvas.drawOval(rect, paint);
+ float da = 4;
+ float arclen = da + da;
+ for (int i = 0; i < 361; i += 90) {
+ float dx = rx + 10;
+ float dy = ry + 10;
+ rect.left = cx - dx;
+ rect.top = cy - dy;
+ rect.right = cx + dx;
+ rect.bottom = cy + dy;
+ canvas.drawArc(rect, i - da, arclen, false, paint);
+ dx = rx - 10;
+ dy = ry - 10;
+ rect.left = cx - dx;
+ rect.top = cy - dy;
+ rect.right = cx + dx;
+ rect.bottom = cy + dy;
+ canvas.drawArc(rect, i - da, arclen, false, paint);
+ }
+ da *= 2;
+ for (int i = 45; i < 361; i += 90) {
+ double angle = Math.PI * i / 180.;
+ float x = cx + (float) (rx * Math.cos(angle));
+ float y = cy + (float) (ry * Math.sin(angle));
+ canvas.drawRect(x - da, y - da, x + da, y + da, paint);
+ }
+ rect.left = cx - rx;
+ rect.top = cy - ry;
+ rect.right = cx + rx;
+ rect.bottom = cy + ry;
+ }
+
+ public void fillHandles(Canvas canvas, float cx, float cy, float rx, float ry) {
+ handlex[0] = cx;
+ handley[0] = cy;
+ int k = 1;
+
+ for (int i = 0; i < 360; i += 45) {
+ double angle = Math.PI * i / 180.;
+
+ float x = cx + (float) (rx * Math.cos(angle));
+ float y = cy + (float) (ry * Math.sin(angle));
+ handlex[k] = x;
+ handley[k] = y;
+
+ k++;
+ }
+ }
+
+ public void draw(Canvas canvas) {
+ paintRadius(canvas, mCenterX, mCenterY, mRadiusX, mRadiusY);
+ fillHandles(canvas, mCenterX, mCenterY, mRadiusX, mRadiusY);
+ paintPoint(canvas, mCenterX, mCenterY);
+ }
+
+ public boolean isUndefined() {
+ return Float.isNaN(mCenterX);
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageDraw.java b/src/com/android/gallery3d/filtershow/imageshow/ImageDraw.java
index 0cd229968..479652ce3 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageDraw.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageDraw.java
@@ -27,11 +27,13 @@ public class ImageDraw extends ImageShow {
public ImageDraw(Context context, AttributeSet attrs) {
super(context, attrs);
resetParameter();
+ super.setOriginalDisabled(true);
}
public ImageDraw(Context context) {
super(context);
resetParameter();
+ super.setOriginalDisabled(true);
}
public void setEditor(EditorDraw editorDraw) {
@@ -82,20 +84,32 @@ public class ImageDraw extends ImageShow {
float[] mTmpPoint = new float[2]; // so we do not malloc
@Override
public boolean onTouchEvent(MotionEvent event) {
- if (event.getPointerCount() != 1) {
- return false;
+ boolean ret = super.onTouchEvent(event);
+ if (event.getPointerCount() > 1) {
+ if (mFRep.getCurrentDrawing() != null) {
+ mFRep.clearCurrentSection();
+ mEditorDraw.commitLocalRepresentation();
+ }
+ return ret;
+ }
+ if (event.getAction() != MotionEvent.ACTION_DOWN) {
+ if (mFRep.getCurrentDrawing() == null) {
+ return ret;
+ }
}
ImageFilterDraw filter = (ImageFilterDraw) getCurrentFilter();
if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ calcScreenMapping();
mTmpPoint[0] = event.getX();
mTmpPoint[1] = event.getY();
mToOrig.mapPoints(mTmpPoint);
mFRep.startNewSection(mType, mCurrentColor, mCurrentSize, mTmpPoint[0], mTmpPoint[1]);
-
}
+
if (event.getAction() == MotionEvent.ACTION_MOVE) {
+
int historySize = event.getHistorySize();
final int pointerCount = event.getPointerCount();
for (int h = 0; h < historySize; h++) {
@@ -108,6 +122,7 @@ public class ImageDraw extends ImageShow {
}
}
}
+
if (event.getAction() == MotionEvent.ACTION_UP) {
mTmpPoint[0] = event.getX();
mTmpPoint[1] = event.getY();
@@ -119,19 +134,10 @@ public class ImageDraw extends ImageShow {
return true;
}
- Matrix mRotateToScreen;
- Matrix mToScreen;
- Matrix mToOrig = new Matrix();
+ Matrix mRotateToScreen = new Matrix();
+ Matrix mToOrig;
private void calcScreenMapping() {
-
- GeometryMetadata geo = getImagePreset().mGeoData;
- mToScreen = geo.getOriginalToScreen(false,
- mImageLoader.getOriginalBounds().width(),
- mImageLoader.getOriginalBounds().height(), getWidth(), getHeight());
- mRotateToScreen = geo.getOriginalToScreen(true,
- mImageLoader.getOriginalBounds().width(),
- mImageLoader.getOriginalBounds().height(), getWidth(), getHeight());
- mRotateToScreen.invert(mToOrig);
+ mToOrig = getScreenToImageMatrix(true);
mToOrig.invert(mRotateToScreen);
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImagePoint.java b/src/com/android/gallery3d/filtershow/imageshow/ImagePoint.java
index 06b055d3c..625cdbe0d 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImagePoint.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImagePoint.java
@@ -75,13 +75,9 @@ public abstract class ImagePoint extends ImageShow {
paint.setColor(Color.RED);
paint.setStrokeWidth(2);
- GeometryMetadata geo = getImagePreset().mGeoData;
- Matrix originalToScreen = geo.getOriginalToScreen(false,
- mImageLoader.getOriginalBounds().width(),
- mImageLoader.getOriginalBounds().height(), getWidth(), getHeight());
- Matrix originalRotateToScreen = geo.getOriginalToScreen(true,
- mImageLoader.getOriginalBounds().width(),
- mImageLoader.getOriginalBounds().height(), getWidth(), getHeight());
+ Matrix originalToScreen = getImageToScreenMatrix(false);
+ Matrix originalRotateToScreen = getImageToScreenMatrix(true);
+
if (mRedEyeRep != null) {
for (FilterPoint candidate : mRedEyeRep.getCandidates()) {
drawPoint(candidate, canvas, originalToScreen, originalRotateToScreen, paint);
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageRedEye.java b/src/com/android/gallery3d/filtershow/imageshow/ImageRedEye.java
index c3ff5e151..40433a02e 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageRedEye.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageRedEye.java
@@ -46,6 +46,15 @@ public class ImageRedEye extends ImagePoint {
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
+
+ if (event.getPointerCount() > 1) {
+ return true;
+ }
+
+ if (didFinishScalingOperation()) {
+ return true;
+ }
+
float ex = event.getX();
float ey = event.getY();
@@ -62,16 +71,8 @@ public class ImageRedEye extends ImagePoint {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (mCurrentRect != null) {
// transform to original coordinates
- GeometryMetadata geo = getImagePreset().mGeoData;
- Matrix originalToScreen = geo.getOriginalToScreen(true,
- mImageLoader.getOriginalBounds().width(),
- mImageLoader.getOriginalBounds().height(),
- getWidth(), getHeight());
- Matrix originalNoRotateToScreen = geo.getOriginalToScreen(false,
- mImageLoader.getOriginalBounds().width(),
- mImageLoader.getOriginalBounds().height(),
- getWidth(), getHeight());
-
+ Matrix originalNoRotateToScreen = getImageToScreenMatrix(false);
+ Matrix originalToScreen = getImageToScreenMatrix(true);
Matrix invert = new Matrix();
originalToScreen.invert(invert);
RectF r = new RectF(mCurrentRect);
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java b/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java
index 463756839..39e0cc82b 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java
@@ -17,38 +17,28 @@
package com.android.gallery3d.filtershow.imageshow;
import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.RectF;
+import android.graphics.*;
import android.net.Uri;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
-import android.view.GestureDetector;
+import android.view.*;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
-import android.view.MotionEvent;
-import android.view.View;
import android.widget.LinearLayout;
-import android.widget.SeekBar;
-import android.widget.SeekBar.OnSeekBarChangeListener;
import com.android.gallery3d.filtershow.FilterShowActivity;
import com.android.gallery3d.filtershow.PanelController;
import com.android.gallery3d.filtershow.cache.ImageLoader;
+import com.android.gallery3d.filtershow.cache.RenderingRequestCaller;
import com.android.gallery3d.filtershow.filters.ImageFilter;
import com.android.gallery3d.filtershow.presets.ImagePreset;
-import com.android.gallery3d.filtershow.ui.SliderListener;
import java.io.File;
public class ImageShow extends View implements OnGestureListener,
- OnDoubleTapListener,
- SliderListener,
- OnSeekBarChangeListener {
+ ScaleGestureDetector.OnScaleGestureListener,
+ OnDoubleTapListener {
private static final String LOGTAG = "ImageShow";
@@ -64,9 +54,10 @@ public class ImageShow extends View implements OnGestureListener,
private static int mBackgroundColor = Color.RED;
private GestureDetector mGestureDetector = null;
+ private ScaleGestureDetector mScaleGestureDetector = null;
protected Rect mImageBounds = new Rect();
-
+ private boolean mOriginalDisabled = false;
private boolean mTouchShowOriginal = false;
private long mTouchShowOriginalDate = 0;
private final long mTouchShowOriginalDelayMin = 200; // 200ms
@@ -75,10 +66,9 @@ public class ImageShow extends View implements OnGestureListener,
private static int UNVEIL_HORIZONTAL = 1;
private static int UNVEIL_VERTICAL = 2;
- private int mTouchDownX = 0;
- private int mTouchDownY = 0;
- protected float mTouchX = 0;
- protected float mTouchY = 0;
+ private Point mTouchDown = new Point();
+ private Point mTouch = new Point();
+ private boolean mFinishedScalingOperation = false;
private static int mOriginalTextMargin = 8;
private static int mOriginalTextSize = 26;
@@ -88,16 +78,10 @@ public class ImageShow extends View implements OnGestureListener,
return new GeometryMetadata(getImagePreset().mGeoData);
}
- public void setGeometry(GeometryMetadata d) {
- getImagePreset().mGeoData.set(d);
- }
-
- private boolean mShowControls = false;
private String mToast = null;
private boolean mShowToast = false;
private boolean mImportantToast = false;
- private SeekBar mSeekBar = null;
private PanelController mController = null;
private FilterShowActivity mActivity = null;
@@ -137,30 +121,9 @@ public class ImageShow extends View implements OnGestureListener,
private final Handler mHandler = new Handler();
public void select() {
- if (mSeekBar != null) {
- mSeekBar.setOnSeekBarChangeListener(this);
- }
- }
-
- private int parameterToUI(int parameter, int minp, int maxp, int uimax) {
- return (uimax * (parameter - minp)) / (maxp - minp);
- }
-
- private int uiToParameter(int ui, int minp, int maxp, int uimax) {
- return ((maxp - minp) * ui) / uimax + minp;
- }
-
- public void updateSeekBar(int parameter, int minp, int maxp) {
- if (mSeekBar == null) {
- return;
- }
- int seekMax = mSeekBar.getMax();
- int progress = parameterToUI(parameter, minp, maxp, seekMax);
- mSeekBar.setProgress(progress);
}
public void unselect() {
-
}
public boolean hasModifications() {
@@ -182,7 +145,6 @@ public class ImageShow extends View implements OnGestureListener,
return mController;
}
- @Override
public void onNewValue(int parameter) {
if (getImagePreset() != null) {
getImagePreset().fillImageStateAdapter(MasterImage.getImage().getState());
@@ -194,15 +156,8 @@ public class ImageShow extends View implements OnGestureListener,
mActivity.enableSave(hasModifications());
}
- @Override
- public void onTouchDown(float x, float y) {
- mTouchX = x;
- mTouchY = y;
- invalidate();
- }
-
- @Override
- public void onTouchUp() {
+ public Point getTouchPoint() {
+ return mTouch;
}
public ImageShow(Context context, AttributeSet attrs) {
@@ -223,6 +178,7 @@ public class ImageShow extends View implements OnGestureListener,
public void setupGestureDetector(Context context) {
mGestureDetector = new GestureDetector(context, this);
+ mScaleGestureDetector = new ScaleGestureDetector(context, this);
}
@Override
@@ -232,10 +188,6 @@ public class ImageShow extends View implements OnGestureListener,
setMeasuredDimension(parentWidth, parentHeight);
}
- public void setSeekBar(SeekBar seekBar) {
- mSeekBar = seekBar;
- }
-
public ImageFilter getCurrentFilter() {
return MasterImage.getImage().getCurrentFilter();
}
@@ -269,6 +221,42 @@ public class ImageShow extends View implements OnGestureListener,
return GeometryMath.roundNearest(getImagePreset().mGeoData.getPreviewCropBounds());
}
+ /* consider moving the following 2 methods into a subclass */
+ /**
+ * This function calculates a Image to Screen Transformation matrix
+ *
+ * @param reflectRotation set true if you want the rotation encoded
+ * @return Image to Screen transformation matrix
+ */
+ protected Matrix getImageToScreenMatrix(boolean reflectRotation) {
+ GeometryMetadata geo = getImagePreset().mGeoData;
+ if (geo == null || mImageLoader == null
+ || mImageLoader.getOriginalBounds() == null) {
+ return new Matrix();
+ }
+ Matrix m = geo.getOriginalToScreen(reflectRotation,
+ mImageLoader.getOriginalBounds().width(),
+ mImageLoader.getOriginalBounds().height(), getWidth(), getHeight());
+ Point translate = MasterImage.getImage().getTranslation();
+ float scaleFactor = MasterImage.getImage().getScaleFactor();
+ m.postTranslate(translate.x, translate.y);
+ m.postScale(scaleFactor, scaleFactor, getWidth()/2.0f, getHeight()/2.0f);
+ return m;
+ }
+
+ /**
+ * This function calculates a to Screen Image Transformation matrix
+ *
+ * @param reflectRotation set true if you want the rotation encoded
+ * @return Screen to Image transformation matrix
+ */
+ protected Matrix getScreenToImageMatrix(boolean reflectRotation) {
+ Matrix m = getImageToScreenMatrix(reflectRotation);
+ Matrix invert = new Matrix();
+ m.invert(invert);
+ return invert;
+ }
+
public Rect getDisplayedImageBounds() {
return mImageBounds;
}
@@ -308,8 +296,18 @@ public class ImageShow extends View implements OnGestureListener,
@Override
public void onDraw(Canvas canvas) {
+ MasterImage.getImage().setImageShowSize(getWidth(), getHeight());
+ canvas.save();
+ // TODO: center scale on gesture
+ float cx = canvas.getWidth()/2.0f;
+ float cy = canvas.getHeight()/2.0f;
+ float scaleFactor = MasterImage.getImage().getScaleFactor();
+ Point translation = MasterImage.getImage().getTranslation();
+ canvas.scale(scaleFactor, scaleFactor, cx, cy);
+ canvas.translate(translation.x, translation.y);
drawBackground(canvas);
defaultDrawImage(canvas);
+ canvas.restore();
if (showTitle() && getImagePreset() != null) {
mPaint.setARGB(200, 0, 0, 0);
@@ -322,6 +320,12 @@ public class ImageShow extends View implements OnGestureListener,
1.5f * mTextPadding, mPaint);
}
+ Bitmap partialPreview = MasterImage.getImage().getPartialImage();
+ if (partialPreview != null) {
+ Rect src = new Rect(0, 0, partialPreview.getWidth(), partialPreview.getHeight());
+ Rect dest = new Rect(0, 0, getWidth(), getHeight());
+ canvas.drawBitmap(partialPreview, src, dest, mPaint);
+ }
drawToast(canvas);
}
@@ -370,7 +374,7 @@ public class ImageShow extends View implements OnGestureListener,
canvas.save();
if (image != null) {
if (mShowOriginalDirection == 0) {
- if ((mTouchY - mTouchDownY) > (mTouchX - mTouchDownX)) {
+ if ((mTouch.y - mTouchDown.y) > (mTouch.x - mTouchDown.x)) {
mShowOriginalDirection = UNVEIL_VERTICAL;
} else {
mShowOriginalDirection = UNVEIL_HORIZONTAL;
@@ -381,9 +385,9 @@ public class ImageShow extends View implements OnGestureListener,
int py = 0;
if (mShowOriginalDirection == UNVEIL_VERTICAL) {
px = mImageBounds.width();
- py = (int) (mTouchY - mImageBounds.top);
+ py = (int) (mTouch.y - mImageBounds.top);
} else {
- px = (int) (mTouchX - mImageBounds.left);
+ px = (int) (mTouch.x - mImageBounds.left);
py = mImageBounds.height();
}
@@ -395,11 +399,11 @@ public class ImageShow extends View implements OnGestureListener,
paint.setColor(Color.BLACK);
if (mShowOriginalDirection == UNVEIL_VERTICAL) {
- canvas.drawLine(mImageBounds.left, mTouchY - 1,
- mImageBounds.right, mTouchY - 1, paint);
+ canvas.drawLine(mImageBounds.left, mTouch.y - 1,
+ mImageBounds.right, mTouch.y - 1, paint);
} else {
- canvas.drawLine(mTouchX - 1, mImageBounds.top,
- mTouchX - 1, mImageBounds.bottom, paint);
+ canvas.drawLine(mTouch.x - 1, mImageBounds.top,
+ mTouch.x - 1, mImageBounds.bottom, paint);
}
Rect bounds = new Rect();
@@ -435,34 +439,10 @@ public class ImageShow extends View implements OnGestureListener,
}
}
- public ImageShow setShowControls(boolean value) {
- mShowControls = value;
- if (mShowControls) {
- if (mSeekBar != null) {
- mSeekBar.setVisibility(View.VISIBLE);
- }
- } else {
- if (mSeekBar != null) {
- mSeekBar.setVisibility(View.INVISIBLE);
- }
- }
- return this;
- }
-
- public boolean showControls() {
- return mShowControls;
- }
-
- public boolean showHires() {
- return true;
- }
-
public boolean showTitle() {
return false;
}
-
-
public void setImageLoader(ImageLoader loader) {
mImageLoader = loader;
if (mImageLoader != null) {
@@ -531,35 +511,73 @@ public class ImageShow extends View implements OnGestureListener,
mImageLoader.returnFilteredResult(getImagePreset(), filterShowActivity);
}
+ public boolean scaleInProgress() {
+ return mScaleGestureDetector.isInProgress();
+ }
+
+ protected boolean isOriginalDisabled() {
+ return mOriginalDisabled;
+ }
+
+ protected void setOriginalDisabled(boolean originalDisabled) {
+ mOriginalDisabled = originalDisabled;
+ }
+
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
- if (mGestureDetector != null) {
- mGestureDetector.onTouchEvent(event);
+ mGestureDetector.onTouchEvent(event);
+ boolean scaleInProgress = scaleInProgress();
+ mScaleGestureDetector.onTouchEvent(event);
+ if (!scaleInProgress() && scaleInProgress) {
+ // If we were scaling, the scale will stop but we will
+ // still issue an ACTION_UP. Let the subclasses know.
+ mFinishedScalingOperation = true;
}
+
int ex = (int) event.getX();
int ey = (int) event.getY();
if (event.getAction() == MotionEvent.ACTION_DOWN) {
- mTouchDownX = ex;
- mTouchDownY = ey;
+ mTouchDown.x = ex;
+ mTouchDown.y = ey;
mTouchShowOriginalDate = System.currentTimeMillis();
mShowOriginalDirection = 0;
+ MasterImage.getImage().setOriginalTranslation(MasterImage.getImage().getTranslation());
}
+
if (event.getAction() == MotionEvent.ACTION_MOVE) {
- mTouchX = ex;
- mTouchY = ey;
- if (!mActivity.isShowingHistoryPanel()
+ mTouch.x = ex;
+ mTouch.y = ey;
+
+ if (event.getPointerCount() == 2) {
+ float scaleFactor = MasterImage.getImage().getScaleFactor();
+ if (scaleFactor >= 1) {
+ float translateX = (mTouch.x - mTouchDown.x) / scaleFactor;
+ float translateY = (mTouch.y - mTouchDown.y) / scaleFactor;
+ Point originalTranslation = MasterImage.getImage().getOriginalTranslation();
+ Point translation = MasterImage.getImage().getTranslation();
+ translation.x = (int) (originalTranslation.x + translateX);
+ translation.y = (int) (originalTranslation.y + translateY);
+ MasterImage.getImage().setTranslation(translation);
+ }
+ } else if (!mOriginalDisabled && !mActivity.isShowingHistoryPanel()
&& (System.currentTimeMillis() - mTouchShowOriginalDate
- > mTouchShowOriginalDelayMin)) {
+ > mTouchShowOriginalDelayMin)
+ && event.getPointerCount() == 1) {
mTouchShowOriginal = true;
}
}
+
if (event.getAction() == MotionEvent.ACTION_UP) {
mTouchShowOriginal = false;
- mTouchDownX = 0;
- mTouchDownY = 0;
- mTouchX = 0;
- mTouchY = 0;
+ mTouchDown.x = 0;
+ mTouchDown.y = 0;
+ mTouch.x = 0;
+ mTouch.y = 0;
+ if (MasterImage.getImage().getScaleFactor() <= 1) {
+ MasterImage.getImage().setScaleFactor(1);
+ MasterImage.getImage().resetTranslation();
+ }
}
invalidate();
return true;
@@ -570,48 +588,6 @@ public class ImageShow extends View implements OnGestureListener,
invalidate();
}
- public float getImageRotation() {
- return getImagePreset().mGeoData.getRotation();
- }
-
- public float getImageRotationZoomFactor() {
- return getImagePreset().mGeoData.getScaleFactor();
- }
-
- public void setImageRotation(float r) {
- getImagePreset().mGeoData.setRotation(r);
- }
-
- public void setImageRotationZoomFactor(float f) {
- getImagePreset().mGeoData.setScaleFactor(f);
- }
-
- public void setImageRotation(float imageRotation,
- float imageRotationZoomFactor) {
- float r = getImageRotation();
- if (imageRotation != r) {
- invalidate();
- }
- setImageRotation(imageRotation);
- setImageRotationZoomFactor(imageRotationZoomFactor);
- }
-
- @Override
- public void onProgressChanged(SeekBar arg0, int progress, boolean arg2) {
- int parameter = progress;
- onNewValue(parameter);
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar arg0) {
- // TODO Auto-generated method stub
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar arg0) {
- // TODO Auto-generated method stub
- }
-
@Override
public boolean onDoubleTap(MotionEvent arg0) {
// TODO Auto-generated method stub
@@ -638,13 +614,17 @@ public class ImageShow extends View implements OnGestureListener,
@Override
public boolean onFling(MotionEvent startEvent, MotionEvent endEvent, float arg2, float arg3) {
+ if (mActivity == null) {
+ return false;
+ }
if ((!mActivity.isShowingHistoryPanel() && startEvent.getX() > endEvent.getX())
|| (mActivity.isShowingHistoryPanel() && endEvent.getX() > startEvent.getX())) {
if (!mTouchShowOriginal
|| (mTouchShowOriginal &&
(System.currentTimeMillis() - mTouchShowOriginalDate
< mTouchShowOriginalDelayMax))) {
- mActivity.toggleHistoryPanel();
+ // TODO fix gesture.
+ // mActivity.toggleHistoryPanel();
}
}
return true;
@@ -673,11 +653,46 @@ public class ImageShow extends View implements OnGestureListener,
}
public boolean useUtilityPanel() {
- return false;
+ return true;
}
public void openUtilityPanel(final LinearLayout accessoryViewList) {
// TODO Auto-generated method stub
}
+ @Override
+ public boolean onScale(ScaleGestureDetector detector) {
+ float scaleFactor = MasterImage.getImage().getScaleFactor();
+ scaleFactor = scaleFactor * detector.getScaleFactor();
+ if (scaleFactor > 2) {
+ scaleFactor = 2;
+ }
+ if (scaleFactor < 0.5) {
+ scaleFactor = 0.5f;
+ }
+ MasterImage.getImage().setScaleFactor(scaleFactor);
+ return true;
+ }
+
+ @Override
+ public boolean onScaleBegin(ScaleGestureDetector detector) {
+ return true;
+ }
+
+ @Override
+ public void onScaleEnd(ScaleGestureDetector detector) {
+ if (MasterImage.getImage().getScaleFactor() < 1) {
+ MasterImage.getImage().setScaleFactor(1);
+ invalidate();
+ }
+ }
+
+ public boolean didFinishScalingOperation() {
+ if (mFinishedScalingOperation) {
+ mFinishedScalingOperation = false;
+ return true;
+ }
+ return false;
+ }
+
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java b/src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java
index 7a539da8f..dfd950565 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java
@@ -22,7 +22,6 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
-import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
@@ -110,8 +109,6 @@ public class ImageStraighten extends ImageGeometry {
RectF bounds = drawTransformed(canvas, image, gPaint, o);
// Draw the grid
- Path path = new Path();
- path.addRect(bounds, Path.Direction.CCW);
gPaint.setARGB(255, 255, 255, 255);
gPaint.setStrokeWidth(3);
gPaint.setStyle(Paint.Style.FILL_AND_STROKE);
@@ -122,7 +119,7 @@ public class ImageStraighten extends ImageGeometry {
if (mMode == MODES.MOVE) {
canvas.save();
- canvas.clipPath(path);
+ canvas.clipRect(bounds);
int n = 16;
float step = dWidth / n;
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageTinyPlanet.java b/src/com/android/gallery3d/filtershow/imageshow/ImageTinyPlanet.java
index 3e95d4e15..3795d1f21 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageTinyPlanet.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageTinyPlanet.java
@@ -22,6 +22,7 @@ import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
+import com.android.gallery3d.filtershow.editors.BasicEditor;
import com.android.gallery3d.filtershow.editors.EditorTinyPlanet;
import com.android.gallery3d.filtershow.filters.FilterCurvesRepresentation;
import com.android.gallery3d.filtershow.filters.FilterTinyPlanetRepresentation;
@@ -37,7 +38,7 @@ public class ImageTinyPlanet extends ImageShow {
private float mCenterY = 0;
private float mStartAngle = 0;
private FilterTinyPlanetRepresentation mTinyPlanetRep;
- private EditorTinyPlanet mEditorTinyPlanet;
+ private BasicEditor mEditorTinyPlanet;
public ImageTinyPlanet(Context context) {
super(context);
@@ -94,7 +95,7 @@ public class ImageTinyPlanet extends ImageShow {
mTinyPlanetRep = tinyPlanetRep;
}
- public void setEditor(EditorTinyPlanet editorTinyPlanet) {
+ public void setEditor(BasicEditor editorTinyPlanet) {
mEditorTinyPlanet = editorTinyPlanet;
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageVignette.java b/src/com/android/gallery3d/filtershow/imageshow/ImageVignette.java
new file mode 100644
index 000000000..a51d10276
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageVignette.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package com.android.gallery3d.filtershow.imageshow;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+
+import com.android.gallery3d.filtershow.editors.EditorVignette;
+import com.android.gallery3d.filtershow.filters.FilterVignetteRepresentation;
+
+public class ImageVignette extends ImageShow {
+ private static final String LOGTAG = "ImageVignette";
+
+ private FilterVignetteRepresentation mVignetteRep;
+ private EditorVignette mEditorVignette;
+
+ private int mActiveHandle = -1;
+
+ EclipseControl mElipse;
+
+ public ImageVignette(Context context) {
+ super(context);
+ mElipse = new EclipseControl(context);
+ }
+
+ public ImageVignette(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mElipse = new EclipseControl(context);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ int mask = event.getActionMasked();
+ if (mActiveHandle == -1) {
+ if (MotionEvent.ACTION_DOWN != mask) {
+ return super.onTouchEvent(event);
+ }
+ if (event.getPointerCount() == 1) {
+ mActiveHandle = mElipse.getCloseHandle(event.getX(), event.getY());
+ }
+ if (mActiveHandle == -1) {
+ return super.onTouchEvent(event);
+ }
+ } else {
+ switch (mask) {
+ case MotionEvent.ACTION_UP:
+ mActiveHandle = -1;
+ break;
+ case MotionEvent.ACTION_DOWN:
+ if (event.getPointerCount() == 1) {
+ Log.v(LOGTAG, "################### ACTION_DOWN odd " + mActiveHandle
+ + " touches=1");
+ }
+ break;
+ }
+ }
+ float x = event.getX();
+ float y = event.getY();
+
+ mElipse.setScrToImageMatrix(getScreenToImageMatrix(true));
+
+ switch (mask) {
+ case (MotionEvent.ACTION_DOWN):
+ mElipse.actionDown(x, y, mVignetteRep);
+ break;
+ case (MotionEvent.ACTION_UP):
+ case (MotionEvent.ACTION_MOVE):
+
+ mElipse.actionMove(mActiveHandle, x, y, mVignetteRep);
+ setRepresentation(mVignetteRep);
+ break;
+ }
+ resetImageCaches(this);
+ invalidate();
+ mEditorVignette.commitLocalRepresentation();
+ return true;
+ }
+
+ public void setRepresentation(FilterVignetteRepresentation vignetteRep) {
+ mVignetteRep = vignetteRep;
+ Matrix toImg = getScreenToImageMatrix(false);
+ Matrix toScr = new Matrix();
+ toImg.invert(toScr);
+
+ float[] c = new float[] {
+ mVignetteRep.getCenterX(), mVignetteRep.getCenterY() };
+ if (Float.isNaN(c[0])) {
+ float cx = mImageLoader.getOriginalBounds().width() / 2;
+ float cy = mImageLoader.getOriginalBounds().height() / 2;
+ float rx = Math.min(cx, cy) * .8f;
+ float ry = rx;
+ mVignetteRep.setCenter(cx, cy);
+ mVignetteRep.setRadius(rx, ry);
+
+ c[0] = cx;
+ c[1] = cy;
+ toScr.mapPoints(c);
+ if (getWidth() != 0) {
+ mElipse.setCenter(c[0], c[1]);
+ mElipse.setRadius(c[0] * 0.8f, c[1] * 0.8f);
+ }
+ } else {
+
+ toScr.mapPoints(c);
+
+ mElipse.setCenter(c[0], c[1]);
+ mElipse.setRadius(toScr.mapRadius(mVignetteRep.getRadiusX()),
+ toScr.mapRadius(mVignetteRep.getRadiusY()));
+ }
+ }
+
+ public void setEditor(EditorVignette editorVignette) {
+ mEditorVignette = editorVignette;
+ }
+
+ @Override
+ public void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ setRepresentation(mVignetteRep);
+ mElipse.draw(canvas);
+
+ }
+
+}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageZoom.java b/src/com/android/gallery3d/filtershow/imageshow/ImageZoom.java
index 222519c11..eb568c303 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageZoom.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageZoom.java
@@ -17,11 +17,7 @@
package com.android.gallery3d.filtershow.imageshow;
import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.graphics.RectF;
+import android.graphics.*;
import android.util.AttributeSet;
import android.view.MotionEvent;
@@ -53,9 +49,7 @@ public class ImageZoom extends ImageShow {
mTouchDown = false;
}
- @Override
public void onTouchDown(float x, float y) {
- super.onTouchDown(x, y);
if (mZoomedIn || mTouchDown) {
return;
}
@@ -75,7 +69,8 @@ public class ImageZoom extends ImageShow {
float ratio = (float) getWidth() / (float) getHeight();
float mh = mMaxSize;
float mw = ratio * mh;
- RectF zoomRect = new RectF(mTouchX - mw, mTouchY - mh, mTouchX + mw, mTouchY + mw);
+ Point touch = getTouchPoint();
+ RectF zoomRect = new RectF(touch.x - mw, touch.y - mh, touch.x + mw, touch.y + mw);
inverse.mapRect(zoomRect);
zoomRect.set(zoomRect.centerX() - mw, zoomRect.centerY() - mh,
zoomRect.centerX() + mw, zoomRect.centerY() + mh);
@@ -84,7 +79,6 @@ public class ImageZoom extends ImageShow {
invalidate();
}
- @Override
public void onTouchUp() {
mTouchDown = false;
}
@@ -96,7 +90,7 @@ public class ImageZoom extends ImageShow {
Bitmap filteredImage = null;
if ((mZoomedIn || mTouchDown) && mImageLoader != null) {
filteredImage = mImageLoader.getScaleOneImageForPreset(this, getImagePreset(),
- mZoomBounds, false);
+ mZoomBounds, null, false);
} else {
filteredImage = getFilteredImage();
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java
index 3172c79dc..9eafe2236 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java
@@ -16,8 +16,7 @@
package com.android.gallery3d.filtershow.imageshow;
-import android.graphics.Bitmap;
-import android.graphics.RectF;
+import android.graphics.*;
import com.android.gallery3d.filtershow.FilterShowActivity;
import com.android.gallery3d.filtershow.HistoryAdapter;
@@ -44,6 +43,7 @@ public class MasterImage implements RenderingRequestCaller {
private Bitmap mGeometryOnlyBitmap = null;
private Bitmap mFiltersOnlyBitmap = null;
+ private Bitmap mPartialBitmap = null;
private ImageLoader mLoader = null;
private HistoryAdapter mHistory = null;
@@ -57,6 +57,12 @@ public class MasterImage implements RenderingRequestCaller {
private GeometryMetadata mPreviousGeometry = null;
+ private float mScaleFactor = 1.0f;
+ private Point mTranslation = new Point();
+ private Point mOriginalTranslation = new Point();
+
+ private Point mImageShowSize = new Point();
+
private MasterImage() {
}
@@ -188,6 +194,10 @@ public class MasterImage implements RenderingRequestCaller {
return mGeometryOnlyBitmap;
}
+ public Bitmap getPartialImage() {
+ return mPartialBitmap;
+ }
+
public void notifyObservers() {
for (ImageShow observer : mObservers) {
observer.invalidate();
@@ -216,6 +226,7 @@ public class MasterImage implements RenderingRequestCaller {
}
}
invalidatePreview();
+ needsUpdateFullResPreview();
mActivity.enableSave(hasModifications());
}
@@ -232,11 +243,67 @@ public class MasterImage implements RenderingRequestCaller {
updatePresets(false);
}
+ public void invalidatePartialPreview() {
+ if (mPartialBitmap != null) {
+ mPartialBitmap = null;
+ notifyObservers();
+ }
+ }
+
public void invalidatePreview() {
mFilteredPreview.invalidate();
+ invalidatePartialPreview();
+ needsUpdateFullResPreview();
FilteringPipeline.getPipeline().updatePreviewBuffer();
}
+ public void setImageShowSize(int w, int h) {
+ if (mImageShowSize.x != w || mImageShowSize.y != h) {
+ mImageShowSize.set(w, h);
+ needsUpdateFullResPreview();
+ }
+ }
+
+ private Matrix getImageToScreenMatrix(boolean reflectRotation) {
+ GeometryMetadata geo = mPreset.mGeoData;
+ if (geo == null || mLoader == null
+ || mLoader.getOriginalBounds() == null
+ || mImageShowSize.x == 0) {
+ return new Matrix();
+ }
+ Matrix m = geo.getOriginalToScreen(reflectRotation,
+ mLoader.getOriginalBounds().width(),
+ mLoader.getOriginalBounds().height(), mImageShowSize.x, mImageShowSize.y);
+ Point translate = getTranslation();
+ float scaleFactor = getScaleFactor();
+ m.postTranslate(translate.x, translate.y);
+ m.postScale(scaleFactor, scaleFactor, mImageShowSize.x/2.0f, mImageShowSize.y/2.0f);
+ return m;
+ }
+
+ private Matrix getScreenToImageMatrix(boolean reflectRotation) {
+ Matrix m = getImageToScreenMatrix(reflectRotation);
+ Matrix invert = new Matrix();
+ m.invert(invert);
+ return invert;
+ }
+
+ public void needsUpdateFullResPreview() {
+ if (!mPreset.canDoPartialRendering()) {
+ invalidatePartialPreview();
+ return;
+ }
+ Matrix m = getScreenToImageMatrix(true);
+ RectF r = new RectF(0, 0, mImageShowSize.x, mImageShowSize.y);
+ RectF dest = new RectF();
+ m.mapRect(dest, r);
+ Rect bounds = new Rect();
+ dest.roundOut(bounds);
+ RenderingRequest.post(null, mPreset, RenderingRequest.PARTIAL_RENDERING,
+ this, bounds, new Rect(0, 0, mImageShowSize.x, mImageShowSize.y));
+ invalidatePartialPreview();
+ }
+
@Override
public void available(RenderingRequest request) {
if (request.getBitmap() == null) {
@@ -248,6 +315,10 @@ public class MasterImage implements RenderingRequestCaller {
if (request.getType() == RenderingRequest.FILTERS_RENDERING) {
mFiltersOnlyBitmap = request.getBitmap();
}
+ if (request.getType() == RenderingRequest.PARTIAL_RENDERING) {
+ mPartialBitmap = request.getBitmap();
+ notifyObservers();
+ }
}
public static void reset() {
@@ -263,4 +334,38 @@ public class MasterImage implements RenderingRequestCaller {
listener.geometryChanged();
}
}
+
+ public float getScaleFactor() {
+ return mScaleFactor;
+ }
+
+ public void setScaleFactor(float scaleFactor) {
+ mScaleFactor = scaleFactor;
+ needsUpdateFullResPreview();
+ }
+
+ public Point getTranslation() {
+ return mTranslation;
+ }
+
+ public void setTranslation(Point translation) {
+ mTranslation.x = translation.x;
+ mTranslation.y = translation.y;
+ needsUpdateFullResPreview();
+ }
+
+ public Point getOriginalTranslation() {
+ return mOriginalTranslation;
+ }
+
+ public void setOriginalTranslation(Point originalTranslation) {
+ mOriginalTranslation.x = originalTranslation.x;
+ mOriginalTranslation.y = originalTranslation.y;
+ }
+
+ public void resetTranslation() {
+ mTranslation.x = 0;
+ mTranslation.y = 0;
+ needsUpdateFullResPreview();
+ }
}
diff --git a/src/com/android/gallery3d/filtershow/ui/SliderListener.java b/src/com/android/gallery3d/filtershow/imageshow/Oval.java
index 6d4718d87..28f278f1c 100644
--- a/src/com/android/gallery3d/filtershow/ui/SliderListener.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/Oval.java
@@ -14,10 +14,16 @@
* limitations under the License.
*/
-package com.android.gallery3d.filtershow.ui;
+package com.android.gallery3d.filtershow.imageshow;
+
+public interface Oval {
+ void setCenter(float x, float y);
+ void setRadius(float w, float h);
+ float getCenterX();
+ float getCenterY();
+ float getRadiusX();
+ float getRadiusY();
+ void setRadiusY(float y);
+ void setRadiusX(float x);
-public interface SliderListener {
- public void onNewValue(int value);
- public void onTouchDown(float x, float y);
- public void onTouchUp();
}
diff --git a/src/com/android/gallery3d/filtershow/presets/ImagePreset.java b/src/com/android/gallery3d/filtershow/presets/ImagePreset.java
index 84266c55d..ae5a03414 100644
--- a/src/com/android/gallery3d/filtershow/presets/ImagePreset.java
+++ b/src/com/android/gallery3d/filtershow/presets/ImagePreset.java
@@ -17,6 +17,7 @@
package com.android.gallery3d.filtershow.presets;
import android.graphics.Bitmap;
+import android.graphics.Rect;
import android.util.Log;
import com.android.gallery3d.filtershow.ImageStateAdapter;
@@ -52,6 +53,8 @@ public class ImagePreset {
private boolean mDoApplyFilters = true;
public final GeometryMetadata mGeoData = new GeometryMetadata();
+ private boolean mPartialRendering = false;
+ private Rect mPartialRenderingBounds;
public ImagePreset() {
setup();
@@ -421,6 +424,22 @@ public class ImagePreset {
return bitmap;
}
+ public boolean canDoPartialRendering() {
+ if (mGeoData.hasModifications()) {
+ return false;
+ }
+ for (int i = 0; i < mFilters.size(); i++) {
+ FilterRepresentation representation = null;
+ synchronized (mFilters) {
+ representation = mFilters.elementAt(i);
+ }
+ if (!representation.supportsPartialRendering()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
public void fillImageStateAdapter(ImageStateAdapter imageStateAdapter) {
if (imageStateAdapter == null) {
return;
@@ -446,4 +465,17 @@ public class ImagePreset {
public void setScaleFactor(float value) {
mScaleFactor = value;
}
+
+ public void setPartialRendering(boolean partialRendering, Rect bounds) {
+ mPartialRendering = partialRendering;
+ mPartialRenderingBounds = bounds;
+ }
+
+ public boolean isPartialRendering() {
+ return mPartialRendering;
+ }
+
+ public Rect getPartialRenderingBounds() {
+ return mPartialRenderingBounds;
+ }
}
diff --git a/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java b/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java
index e378fe2b7..89cfa6bdf 100644
--- a/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java
+++ b/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java
@@ -22,6 +22,7 @@ import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
+import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
@@ -173,37 +174,52 @@ public class SaveCopyTask extends AsyncTask<ImagePreset, Void, Uri> {
}
ImagePreset preset = params[0];
InputStream is = null;
- try {
- Bitmap bitmap = ImageLoader.loadMutableBitmap(context, sourceUri);
- if (bitmap == null) {
- return null;
- }
- bitmap = preset.applyGeometry(bitmap);
- bitmap = preset.apply(bitmap);
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ boolean noBitmap = true;
+ int num_tries = 0;
+ // Stopgap fix for low-memory devices.
+ while(noBitmap) {
+ try {
+ // Try to do bitmap operations, downsample if low-memory
+ Bitmap bitmap = ImageLoader.loadMutableBitmap(context, sourceUri, options);
+ if (bitmap == null) {
+ return null;
+ }
+ bitmap = preset.applyGeometry(bitmap);
+ bitmap = preset.apply(bitmap);
- Object xmp = null;
- if (preset.isPanoramaSafe()) {
- is = context.getContentResolver().openInputStream(sourceUri);
- xmp = XmpUtilHelper.extractXMPMeta(is);
- }
- ExifData exif = getExifData(sourceUri);
- if (exif != null) {
- exif.addDateTimeStampTag(ExifTag.TAG_DATE_TIME, System.currentTimeMillis(),
- TimeZone.getDefault());
- // Since the image has been modified, set the orientation to normal.
- exif.addTag(ExifTag.TAG_ORIENTATION).setValue(ExifTag.Orientation.TOP_LEFT);
+ Object xmp = null;
+ if (preset.isPanoramaSafe()) {
+ is = context.getContentResolver().openInputStream(sourceUri);
+ xmp = XmpUtilHelper.extractXMPMeta(is);
+ }
+ ExifData exif = getExifData(sourceUri);
+ if (exif != null) {
+ exif.addDateTimeStampTag(ExifTag.TAG_DATE_TIME, System.currentTimeMillis(),
+ TimeZone.getDefault());
+ // Since the image has been modified, set the orientation to normal.
+ exif.addTag(ExifTag.TAG_ORIENTATION).setValue(ExifTag.Orientation.TOP_LEFT);
+ }
+ saveBitmap(bitmap, this.destinationFile, xmp, exif);
+ bitmap.recycle();
+ noBitmap = false;
+ } catch (FileNotFoundException ex) {
+ Log.w(LOGTAG, "Failed to save image!", ex);
+ return null;
+ } catch (java.lang.OutOfMemoryError e) {
+ // Try 5 times before failing for good.
+ if (++num_tries >= 5) {
+ throw e;
+ }
+ System.gc();
+ options.inSampleSize *= 2;
+ } finally {
+ Utils.closeSilently(is);
}
- saveBitmap(bitmap, this.destinationFile, xmp, exif);
-
- Uri uri = insertContent(context, sourceUri, this.destinationFile, saveFileName);
- bitmap.recycle();
- return uri;
- } catch (FileNotFoundException ex) {
- Log.w(LOGTAG, "Failed to save image!", ex);
- return null;
- } finally {
- Utils.closeSilently(is);
}
+ Uri uri = insertContent(context, sourceUri, this.destinationFile, saveFileName);
+ return uri;
+
}
@Override
diff --git a/src/com/android/gallery3d/filtershow/ui/ImageCurves.java b/src/com/android/gallery3d/filtershow/ui/ImageCurves.java
index f581fc733..e54c83eff 100644
--- a/src/com/android/gallery3d/filtershow/ui/ImageCurves.java
+++ b/src/com/android/gallery3d/filtershow/ui/ImageCurves.java
@@ -233,6 +233,16 @@ public class ImageCurves extends ImageShow {
@Override
public synchronized boolean onTouchEvent(MotionEvent e) {
+ super.onTouchEvent(e);
+
+ if (e.getPointerCount() != 1) {
+ return true;
+ }
+
+ if (didFinishScalingOperation()) {
+ return true;
+ }
+
float posX = e.getX() / getWidth();
float posY = e.getY();
float margin = Spline.curveHandleSize() / 2;
@@ -255,7 +265,6 @@ public class ImageCurves extends ImageShow {
mDoingTouchMove = false;
return true;
}
- mDoingTouchMove = true;
if (mDidDelete) {
return true;
@@ -265,28 +274,31 @@ public class ImageCurves extends ImageShow {
return true;
}
- Spline spline = getSpline(mCurrentCurveIndex);
- int pick = mCurrentPick;
- if (mCurrentControlPoint == null) {
- pick = pickControlPoint(posX, posY);
- if (pick == -1) {
- mCurrentControlPoint = new ControlPoint(posX, posY);
- pick = spline.addPoint(mCurrentControlPoint);
- mDidAddPoint = true;
- } else {
- mCurrentControlPoint = spline.getPoint(pick);
+ if (e.getActionMasked() == MotionEvent.ACTION_MOVE) {
+ mDoingTouchMove = true;
+ Spline spline = getSpline(mCurrentCurveIndex);
+ int pick = mCurrentPick;
+ if (mCurrentControlPoint == null) {
+ pick = pickControlPoint(posX, posY);
+ if (pick == -1) {
+ mCurrentControlPoint = new ControlPoint(posX, posY);
+ pick = spline.addPoint(mCurrentControlPoint);
+ mDidAddPoint = true;
+ } else {
+ mCurrentControlPoint = spline.getPoint(pick);
+ }
+ mCurrentPick = pick;
}
- mCurrentPick = pick;
- }
- if (spline.isPointContained(posX, pick)) {
- spline.movePoint(pick, posX, posY);
- } else if (pick != -1 && spline.getNbPoints() > 2) {
- spline.deletePoint(pick);
- mDidDelete = true;
+ if (spline.isPointContained(posX, pick)) {
+ spline.movePoint(pick, posX, posY);
+ } else if (pick != -1 && spline.getNbPoints() > 2) {
+ spline.deletePoint(pick);
+ mDidDelete = true;
+ }
+ updateCachedImage();
+ invalidate();
}
- updateCachedImage();
- invalidate();
return true;
}
diff --git a/src/com/android/gallery3d/filtershow/ui/SliderController.java b/src/com/android/gallery3d/filtershow/ui/SliderController.java
deleted file mode 100644
index 7139acebb..000000000
--- a/src/com/android/gallery3d/filtershow/ui/SliderController.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * 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.
- */
-
-package com.android.gallery3d.filtershow.ui;
-
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.view.MotionEvent;
-
-public class SliderController {
- private static final String LOGTAG = "SliderController";
-
- private float mCenterX;
- private float mCenterY;
- private float mCurrentX;
- private float mCurrentY;
- private int mValue = 100;
- int mOriginalValue = 0;
-
- private int mWidth = 0;
- private int mHeight = 0;
-
- private String mToast = null;
-
- private final Paint mPaint = new Paint();
-
- private SliderListener mListener = null;
-
- private MODES mMode = MODES.NONE;
- private static int mTextSize = 128;
-
- private enum MODES {
- NONE, DOWN, UP, MOVE
- }
-
- public void onDraw(Canvas canvas) {
- if (mMode == MODES.NONE || mMode == MODES.UP) {
- return;
- }
- }
-
- public void drawToast(Canvas canvas) {
- if (mToast != null) {
- canvas.save();
- mPaint.setTextSize(mTextSize);
- float textWidth = mPaint.measureText(mToast);
- int toastX = (int) ((getWidth() - textWidth) / 2.0f);
- int toastY = (int) (getHeight() / 3.0f);
-
- mPaint.setARGB(255, 0, 0, 0);
- canvas.drawText(mToast, toastX - 2, toastY - 2, mPaint);
- canvas.drawText(mToast, toastX - 2, toastY, mPaint);
- canvas.drawText(mToast, toastX, toastY - 2, mPaint);
- canvas.drawText(mToast, toastX + 2, toastY + 2, mPaint);
- canvas.drawText(mToast, toastX + 2, toastY, mPaint);
- canvas.drawText(mToast, toastX, toastY + 2, mPaint);
- mPaint.setARGB(255, 255, 255, 255);
- canvas.drawText(mToast, toastX, toastY, mPaint);
- canvas.restore();
- }
- }
-
- protected int computeValue() {
- int delta = (int) (100 * (getCurrentX() - getCenterX()) / getWidth());
- int value = mOriginalValue + delta;
- if (value < -100) {
- value = -100;
- } else if (value > 100) {
- value = 100;
- }
- setValue(value);
- mToast = "" + value;
- return value;
- }
-
- public void setValue(int value) {
- mValue = value;
- }
-
- public int getWidth() {
- return mWidth;
- }
-
- public int getHeight() {
- return mHeight;
- }
-
- public void setWidth(int value) {
- mWidth = value;
- }
-
- public void setHeight(int value) {
- mHeight = value;
- }
-
- public float getCurrentX() {
- return mCurrentX;
- }
-
- public float getCurrentY() {
- return mCurrentY;
- }
-
- public float getCenterX() {
- return mCenterX;
- }
-
- public float getCenterY() {
- return mCenterY;
- }
-
- public void setActionDown(float x, float y) {
- mCenterX = x;
- mCenterY = y;
- mCurrentX = x;
- mCurrentY = y;
- mMode = MODES.DOWN;
- if (mListener != null) {
- mListener.onTouchDown(x, y);
- }
- }
-
- public void setActionMove(float x, float y) {
- mCurrentX = x;
- mCurrentY = y;
- mMode = MODES.MOVE;
- computeValue();
- if (mListener != null) {
- mListener.onNewValue(mValue);
- }
- }
-
- public void setActionUp() {
- mMode = MODES.UP;
- mOriginalValue = computeValue();
- if (mListener != null) {
- mListener.onTouchUp();
- }
- }
-
- public void setNoAction() {
- mMode = MODES.NONE;
- }
-
- public void setListener(SliderListener listener) {
- mListener = listener;
- }
-
- public boolean onTouchEvent(MotionEvent event) {
- setNoAction();
- switch (event.getActionMasked()) {
- case (MotionEvent.ACTION_DOWN): {
- setActionDown(event.getX(), event.getY());
- break;
- }
- case (MotionEvent.ACTION_UP): {
- setActionUp();
- break;
- }
- case (MotionEvent.ACTION_CANCEL): {
- setActionUp();
- break;
- }
- case (MotionEvent.ACTION_MOVE): {
- setActionMove(event.getX(), event.getY());
- break;
- }
- }
- return true;
- }
-
- public void reset() {
- mOriginalValue = 0;
- }
-
-}
diff --git a/src_pd/com/android/gallery3d/filtershow/editors/EditorManager.java b/src_pd/com/android/gallery3d/filtershow/editors/EditorManager.java
index 67ccf9c80..92962cbb1 100644
--- a/src_pd/com/android/gallery3d/filtershow/editors/EditorManager.java
+++ b/src_pd/com/android/gallery3d/filtershow/editors/EditorManager.java
@@ -28,6 +28,7 @@ public class EditorManager {
editorPlaceHolder.addEditor(new EditorCurves());
editorPlaceHolder.addEditor(new EditorTinyPlanet());
editorPlaceHolder.addEditor(new EditorDraw());
+ editorPlaceHolder.addEditor(new EditorVignette());
}
}
diff --git a/tests/src/com/android/gallery3d/StressTests.java b/tests/src/com/android/gallery3d/StressTests.java
index 32eefdcec..b991e9e8d 100755
--- a/tests/src/com/android/gallery3d/StressTests.java
+++ b/tests/src/com/android/gallery3d/StressTests.java
@@ -41,7 +41,7 @@ public class StressTests extends TestSuite {
result.addTestSuite(CameraLatency.class);
result.addTestSuite(CameraStartUp.class);
result.addTestSuite(ImageCapture.class);
- result.addTestSuite(SwitchPreview.class);
+// result.addTestSuite(SwitchPreview.class);
return result;
}
}
diff --git a/tests/src/com/android/gallery3d/stress/CameraStressTestRunner.java b/tests/src/com/android/gallery3d/stress/CameraStressTestRunner.java
index 57ae69125..d3fb10dad 100755
--- a/tests/src/com/android/gallery3d/stress/CameraStressTestRunner.java
+++ b/tests/src/com/android/gallery3d/stress/CameraStressTestRunner.java
@@ -25,8 +25,8 @@ public class CameraStressTestRunner extends InstrumentationTestRunner {
// Default recorder settings
public static int mVideoDuration = 20000; // set default to 20 seconds
- public static int mVideoIterations = 100; // set default to 100 videos
- public static int mImageIterations = 100; // set default to 100 images
+ public static int mVideoIterations = 1; // set default to 1 video
+ public static int mImageIterations = 10; // set default to 10 images
@Override
public TestSuite getAllTests() {