From e5498da0262fc836738aad63ea30286d8afa643c Mon Sep 17 00:00:00 2001 From: nicolasroard Date: Thu, 21 Feb 2013 15:52:49 -0800 Subject: [PATCH] Pinch to zoom refine Change-Id: I538defa55a4ed898dd7c936ec813f052ac1b9e0a --- .../gallery3d/filtershow/PanelController.java | 8 ++- .../filtershow/cache/FilteringPipeline.java | 44 ++++++++++-- .../gallery3d/filtershow/cache/ImageLoader.java | 21 ++++-- .../filtershow/cache/RenderingRequest.java | 50 +++++++++++--- .../filters/FilterCurvesRepresentation.java | 1 + .../filtershow/filters/FilterFxRepresentation.java | 1 + .../filtershow/filters/FilterRepresentation.java | 11 +++ .../filtershow/filters/ImageFilterBwFilter.java | 1 + .../filtershow/filters/ImageFilterContrast.java | 1 + .../filtershow/filters/ImageFilterEdge.java | 1 + .../filtershow/filters/ImageFilterExposure.java | 1 + .../filtershow/filters/ImageFilterHighlights.java | 1 + .../filtershow/filters/ImageFilterHue.java | 1 + .../filtershow/filters/ImageFilterKMeans.java | 1 + .../filtershow/filters/ImageFilterNegative.java | 1 + .../filtershow/filters/ImageFilterSaturated.java | 1 + .../filtershow/filters/ImageFilterShadows.java | 1 + .../filtershow/filters/ImageFilterSharpen.java | 3 +- .../filtershow/filters/ImageFilterVibrance.java | 1 + .../filtershow/filters/ImageFilterWBalance.java | 1 + .../gallery3d/filtershow/imageshow/ImageShow.java | 17 ++++- .../gallery3d/filtershow/imageshow/ImageZoom.java | 2 +- .../filtershow/imageshow/MasterImage.java | 78 ++++++++++++++++++++-- .../gallery3d/filtershow/presets/ImagePreset.java | 32 +++++++++ 24 files changed, 251 insertions(+), 29 deletions(-) diff --git a/src/com/android/gallery3d/filtershow/PanelController.java b/src/com/android/gallery3d/filtershow/PanelController.java index cff07ff61..5bda246da 100644 --- a/src/com/android/gallery3d/filtershow/PanelController.java +++ b/src/com/android/gallery3d/filtershow/PanelController.java @@ -375,11 +375,13 @@ 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; @@ -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(); @@ -555,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 42e72e665..25bb6b60a 100644 --- a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java +++ b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java @@ -265,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) { @@ -370,11 +370,24 @@ 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 (bmp != null) { // TODO: this workaround for RS might not be needed ultimately Bitmap bmp2 = bmp.copy(Bitmap.Config.ARGB_8888, true); 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/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/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/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 index b9a14652a..12f032dcd 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterHighlights.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterHighlights.java @@ -41,6 +41,7 @@ public class ImageFilterHighlights 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/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/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/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/imageshow/ImageShow.java b/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java index b91ebd195..39e0cc82b 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java +++ b/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java @@ -21,15 +21,16 @@ import android.graphics.*; import android.net.Uri; import android.os.Handler; import android.util.AttributeSet; +import android.util.Log; import android.view.*; import android.view.GestureDetector.OnDoubleTapListener; import android.view.GestureDetector.OnGestureListener; import android.widget.LinearLayout; -import com.android.gallery3d.app.Log; 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; @@ -229,6 +230,10 @@ public class ImageShow extends View implements OnGestureListener, */ 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()); @@ -291,7 +296,7 @@ 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; @@ -315,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); } @@ -547,6 +558,7 @@ public class ImageShow extends View implements OnGestureListener, 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 @@ -682,4 +694,5 @@ public class ImageShow extends View implements OnGestureListener, } return false; } + } diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageZoom.java b/src/com/android/gallery3d/filtershow/imageshow/ImageZoom.java index 0e32dc1e1..eb568c303 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageZoom.java +++ b/src/com/android/gallery3d/filtershow/imageshow/ImageZoom.java @@ -90,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 905d2c390..9eafe2236 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java +++ b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java @@ -16,9 +16,7 @@ package com.android.gallery3d.filtershow.imageshow; -import android.graphics.Bitmap; -import android.graphics.Point; -import android.graphics.RectF; +import android.graphics.*; import com.android.gallery3d.filtershow.FilterShowActivity; import com.android.gallery3d.filtershow.HistoryAdapter; @@ -45,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; @@ -62,6 +61,8 @@ public class MasterImage implements RenderingRequestCaller { private Point mTranslation = new Point(); private Point mOriginalTranslation = new Point(); + private Point mImageShowSize = new Point(); + private MasterImage() { } @@ -193,6 +194,10 @@ public class MasterImage implements RenderingRequestCaller { return mGeometryOnlyBitmap; } + public Bitmap getPartialImage() { + return mPartialBitmap; + } + public void notifyObservers() { for (ImageShow observer : mObservers) { observer.invalidate(); @@ -221,6 +226,7 @@ public class MasterImage implements RenderingRequestCaller { } } invalidatePreview(); + needsUpdateFullResPreview(); mActivity.enableSave(hasModifications()); } @@ -237,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) { @@ -253,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() { @@ -275,6 +341,7 @@ public class MasterImage implements RenderingRequestCaller { public void setScaleFactor(float scaleFactor) { mScaleFactor = scaleFactor; + needsUpdateFullResPreview(); } public Point getTranslation() { @@ -282,7 +349,9 @@ public class MasterImage implements RenderingRequestCaller { } public void setTranslation(Point translation) { - mTranslation = translation; + mTranslation.x = translation.x; + mTranslation.y = translation.y; + needsUpdateFullResPreview(); } public Point getOriginalTranslation() { @@ -297,5 +366,6 @@ public class MasterImage implements RenderingRequestCaller { public void resetTranslation() { mTranslation.x = 0; mTranslation.y = 0; + needsUpdateFullResPreview(); } } 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; + } } -- 2.11.0