diff options
Diffstat (limited to 'src/com/android/gallery3d')
61 files changed, 1152 insertions, 705 deletions
diff --git a/src/com/android/gallery3d/app/AlbumPage.java b/src/com/android/gallery3d/app/AlbumPage.java index 001ce87b7..658abbbd4 100644 --- a/src/com/android/gallery3d/app/AlbumPage.java +++ b/src/com/android/gallery3d/app/AlbumPage.java @@ -39,7 +39,7 @@ import com.android.gallery3d.data.MediaItem; import com.android.gallery3d.data.MediaObject; import com.android.gallery3d.data.MediaSet; import com.android.gallery3d.data.Path; -import com.android.gallery3d.filtershow.FilterShowActivity; +import com.android.gallery3d.filtershow.crop.CropActivity; import com.android.gallery3d.filtershow.crop.CropExtras; import com.android.gallery3d.glrenderer.FadeTexture; import com.android.gallery3d.glrenderer.GLCanvas; @@ -318,7 +318,7 @@ public class AlbumPage extends ActivityState implements GalleryActionBar.Cluster Activity activity = mActivity; if (mData.getString(Gallery.EXTRA_CROP) != null) { Uri uri = dm.getContentUri(item.getPath()); - Intent intent = new Intent(FilterShowActivity.CROP_ACTION, uri) + Intent intent = new Intent(CropActivity.CROP_ACTION, uri) .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT) .putExtras(getData()); if (mData.getParcelable(MediaStore.EXTRA_OUTPUT) == null) { diff --git a/src/com/android/gallery3d/app/CommonControllerOverlay.java b/src/com/android/gallery3d/app/CommonControllerOverlay.java index a4f5807ae..9adb4e7a8 100644 --- a/src/com/android/gallery3d/app/CommonControllerOverlay.java +++ b/src/com/android/gallery3d/app/CommonControllerOverlay.java @@ -66,6 +66,10 @@ public abstract class CommonControllerOverlay extends FrameLayout implements protected boolean mCanReplay = true; + public void setSeekable(boolean canSeek) { + mTimeBar.setSeekable(canSeek); + } + public CommonControllerOverlay(Context context) { super(context); diff --git a/src/com/android/gallery3d/app/MoviePlayer.java b/src/com/android/gallery3d/app/MoviePlayer.java index 00e4cd63b..ce9183483 100644 --- a/src/com/android/gallery3d/app/MoviePlayer.java +++ b/src/com/android/gallery3d/app/MoviePlayer.java @@ -25,7 +25,6 @@ import android.content.DialogInterface.OnCancelListener; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.IntentFilter; -import android.graphics.Color; import android.media.AudioManager; import android.media.MediaPlayer; import android.net.Uri; @@ -135,6 +134,17 @@ public class MoviePlayer implements return true; } }); + mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override + public void onPrepared(MediaPlayer player) { + if (!mVideoView.canSeekForward() || !mVideoView.canSeekBackward()) { + mController.setSeekable(false); + } else { + mController.setSeekable(true); + } + setProgress(); + } + }); // The SurfaceView is transparent before drawing the first frame. // This makes the UI flashing when open a video. (black -> old screen diff --git a/src/com/android/gallery3d/app/TimeBar.java b/src/com/android/gallery3d/app/TimeBar.java index 402dfcfab..246346a56 100644 --- a/src/com/android/gallery3d/app/TimeBar.java +++ b/src/com/android/gallery3d/app/TimeBar.java @@ -259,4 +259,8 @@ public class TimeBar extends View { } } + public void setSeekable(boolean canSeek) { + mShowScrubber = canSeek; + } + } diff --git a/src/com/android/gallery3d/app/Wallpaper.java b/src/com/android/gallery3d/app/Wallpaper.java index 91bc77271..b0a26c236 100644 --- a/src/com/android/gallery3d/app/Wallpaper.java +++ b/src/com/android/gallery3d/app/Wallpaper.java @@ -26,7 +26,7 @@ import android.os.Bundle; import android.view.Display; import com.android.gallery3d.common.ApiHelper; -import com.android.gallery3d.filtershow.FilterShowActivity; +import com.android.gallery3d.filtershow.crop.CropActivity; import com.android.gallery3d.filtershow.crop.CropExtras; /** @@ -100,7 +100,7 @@ public class Wallpaper extends Activity { Point size = getDefaultDisplaySize(new Point()); float spotlightX = (float) size.x / width; float spotlightY = (float) size.y / height; - Intent request = new Intent(FilterShowActivity.CROP_ACTION) + Intent request = new Intent(CropActivity.CROP_ACTION) .setDataAndType(mPickedItem, IMAGE_TYPE) .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT) .putExtra(CropExtras.KEY_OUTPUT_X, width) diff --git a/src/com/android/gallery3d/filtershow/FilterShowActivity.java b/src/com/android/gallery3d/filtershow/FilterShowActivity.java index 67ae3b53a..bdcd83c5e 100644 --- a/src/com/android/gallery3d/filtershow/FilterShowActivity.java +++ b/src/com/android/gallery3d/filtershow/FilterShowActivity.java @@ -19,7 +19,6 @@ package com.android.gallery3d.filtershow; import android.app.ActionBar; import android.app.AlertDialog; import android.app.ProgressDialog; -import android.app.WallpaperManager; import android.content.ContentValues; import android.content.DialogInterface; import android.content.Intent; @@ -36,7 +35,6 @@ import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentTransaction; import android.util.DisplayMetrics; -import android.util.Log; import android.util.TypedValue; import android.view.Display; import android.view.Menu; @@ -49,17 +47,35 @@ import android.widget.AdapterView.OnItemClickListener; import android.widget.FrameLayout; import android.widget.ShareActionProvider; import android.widget.ShareActionProvider.OnShareTargetSelectedListener; - import android.widget.Toast; + import com.android.gallery3d.R; import com.android.gallery3d.data.LocalAlbum; import com.android.gallery3d.filtershow.cache.CachingPipeline; import com.android.gallery3d.filtershow.cache.FilteringPipeline; import com.android.gallery3d.filtershow.cache.ImageLoader; -import com.android.gallery3d.filtershow.category.*; -import com.android.gallery3d.filtershow.crop.CropExtras; -import com.android.gallery3d.filtershow.editors.*; -import com.android.gallery3d.filtershow.filters.*; +import com.android.gallery3d.filtershow.category.Action; +import com.android.gallery3d.filtershow.category.CategoryAdapter; +import com.android.gallery3d.filtershow.category.CategoryView; +import com.android.gallery3d.filtershow.category.MainPanel; +import com.android.gallery3d.filtershow.editors.BasicEditor; +import com.android.gallery3d.filtershow.editors.Editor; +import com.android.gallery3d.filtershow.editors.EditorCrop; +import com.android.gallery3d.filtershow.editors.EditorDraw; +import com.android.gallery3d.filtershow.editors.EditorFlip; +import com.android.gallery3d.filtershow.editors.EditorInfo; +import com.android.gallery3d.filtershow.editors.EditorManager; +import com.android.gallery3d.filtershow.editors.EditorPanel; +import com.android.gallery3d.filtershow.editors.EditorRedEye; +import com.android.gallery3d.filtershow.editors.EditorRotate; +import com.android.gallery3d.filtershow.editors.EditorStraighten; +import com.android.gallery3d.filtershow.editors.EditorTinyPlanet; +import com.android.gallery3d.filtershow.editors.ImageOnlyEditor; +import com.android.gallery3d.filtershow.filters.FilterFxRepresentation; +import com.android.gallery3d.filtershow.filters.FilterImageBorderRepresentation; +import com.android.gallery3d.filtershow.filters.FilterRepresentation; +import com.android.gallery3d.filtershow.filters.FiltersManager; +import com.android.gallery3d.filtershow.filters.ImageFilter; import com.android.gallery3d.filtershow.imageshow.GeometryMetadata; import com.android.gallery3d.filtershow.imageshow.ImageCrop; import com.android.gallery3d.filtershow.imageshow.ImageShow; @@ -67,24 +83,21 @@ 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.state.StateAdapter; -import com.android.gallery3d.filtershow.tools.BitmapTask; import com.android.gallery3d.filtershow.tools.SaveCopyTask; +import com.android.gallery3d.filtershow.tools.XmpPresets; +import com.android.gallery3d.filtershow.tools.XmpPresets.XMresults; import com.android.gallery3d.filtershow.ui.FramedTextButton; import com.android.gallery3d.filtershow.ui.Spline; import com.android.gallery3d.util.GalleryUtils; import com.android.photos.data.GalleryBitmapPool; import java.io.File; -import java.io.IOException; import java.lang.ref.WeakReference; import java.util.Vector; public class FilterShowActivity extends FragmentActivity implements OnItemClickListener, OnShareTargetSelectedListener { - // fields for supporting crop action - public static final String CROP_ACTION = "com.android.camera.action.CROP"; - private CropExtras mCropExtras = null; private String mAction = ""; MasterImage mMasterImage = null; @@ -92,7 +105,6 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL public static final String TINY_PLANET_ACTION = "com.android.camera.action.TINY_PLANET"; public static final String LAUNCH_FULLSCREEN = "launch-fullscreen"; - public static final int MAX_BMAP_IN_INTENT = 990000; private ImageLoader mImageLoader = null; private ImageShow mImageShow = null; @@ -119,6 +131,9 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL private LoadBitmapTask mLoadBitmapTask; private boolean mLoading = true; + private Uri mOriginalImageUri = null; + private ImagePreset mOriginalPreset = null; + private CategoryAdapter mCategoryLooksAdapter = null; private CategoryAdapter mCategoryBordersAdapter = null; private CategoryAdapter mCategoryGeometryAdapter = null; @@ -147,6 +162,7 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL setDefaultPreset(); + extractXMPData(); processIntent(); } @@ -167,7 +183,6 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL public void loadEditorPanel(FilterRepresentation representation, final Editor currentEditor) { if (representation.getEditorId() == ImageOnlyEditor.ID) { - currentEditor.getImageShow().select(); currentEditor.reflectCurrentFilter(); return; } @@ -285,9 +300,12 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL } mAction = intent.getAction(); - - if (intent.getData() != null) { - startLoadBitmap(intent.getData()); + Uri srcUri = intent.getData(); + if (mOriginalImageUri != null) { + srcUri = mOriginalImageUri; + } + if (srcUri != null) { + startLoadBitmap(srcUri); } else { pickImage(); } @@ -321,16 +339,10 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL CategoryView.setMargin((int) getPixelsFromDip(8)); CategoryView.setTextSize((int) getPixelsFromDip(16)); - ImageShow.setDefaultBackgroundColor(res.getColor(R.color.background_screen)); // TODO: get those values from XML. FramedTextButton.setTextSize((int) getPixelsFromDip(14)); FramedTextButton.setTrianglePadding((int) getPixelsFromDip(4)); FramedTextButton.setTriangleSize((int) getPixelsFromDip(10)); - ImageShow.setTextSize((int) getPixelsFromDip(12)); - ImageShow.setTextPadding((int) getPixelsFromDip(10)); - ImageShow.setOriginalTextMargin((int) getPixelsFromDip(4)); - ImageShow.setOriginalTextSize((int) getPixelsFromDip(18)); - ImageShow.setOriginalText(res.getString(R.string.original_picture_text)); Drawable curveHandle = res.getDrawable(R.drawable.camera_crop); int curveHandleSize = (int) res.getDimension(R.dimen.crop_indicator_size); @@ -364,8 +376,9 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL for (int i = 0; i < borders.size(); i++) { FilterRepresentation filter = borders.elementAt(i); + filter.setScrName(getString(R.string.borders)); if (i == 0) { - filter.setName(getString(R.string.none)); + filter.setScrName(getString(R.string.none)); } } @@ -519,6 +532,11 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL mCategoryFiltersAdapter.imageLoaded(); mLoadBitmapTask = null; + if (mOriginalPreset != null) { + MasterImage.getImage().setPreset(mOriginalPreset, true); + mOriginalPreset = null; + } + if (mAction == TINY_PLANET_ACTION) { showRepresentation(mCategoryFiltersAdapter.getTinyPlanet()); } @@ -720,7 +738,6 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL HistoryAdapter adapter = mMasterImage.getHistory(); int position = adapter.undo(); mMasterImage.onHistoryItemClick(position); - mImageShow.showToast("Undo"); backToMain(); invalidateViews(); return true; @@ -729,7 +746,6 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL HistoryAdapter adapter = mMasterImage.getHistory(); int position = adapter.redo(); mMasterImage.onHistoryItemClick(position); - mImageShow.showToast("Redo"); invalidateViews(); return true; } @@ -903,9 +919,7 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL } public void cannotLoadImage() { - CharSequence text = getString(R.string.cannot_load_image); - Toast toast = Toast.makeText(this, text, Toast.LENGTH_SHORT); - toast.show(); + Toast.makeText(this, R.string.cannot_load_image, Toast.LENGTH_SHORT).show(); finish(); } @@ -942,111 +956,23 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL } } - private boolean mSaveToExtraUri = false; - private boolean mSaveAsWallpaper = false; - private boolean mReturnAsExtra = false; - private boolean mOutputted = false; public void saveImage() { - handleSpecialExitCases(); - if (!mOutputted) { - if (mImageShow.hasModifications()) { - // Get the name of the album, to which the image will be saved - File saveDir = SaveCopyTask.getFinalSaveDirectory(this, mImageLoader.getUri()); - int bucketId = GalleryUtils.getBucketId(saveDir.getPath()); - String albumName = LocalAlbum.getLocalizedName(getResources(), bucketId, null); - showSavingProgress(albumName); - mImageShow.saveImage(this, null); - } else { - done(); - } - } - } - - public boolean detectSpecialExitCases() { - return mCropExtras != null && (mCropExtras.getExtraOutput() != null - || mCropExtras.getSetAsWallpaper() || mCropExtras.getReturnData()); - } - - public void handleSpecialExitCases() { - if (mCropExtras != null) { - if (mCropExtras.getExtraOutput() != null) { - mSaveToExtraUri = true; - mOutputted = true; - } - if (mCropExtras.getSetAsWallpaper()) { - mSaveAsWallpaper = true; - mOutputted = true; - } - if (mCropExtras.getReturnData()) { - mReturnAsExtra = true; - mOutputted = true; - } - if (mOutputted) { - mImageShow.getImagePreset().mGeoData.setUseCropExtrasFlag(true); - showSavingProgress(null); - mImageShow.returnFilteredResult(this); - } - } - } - - public void onFilteredResult(Bitmap filtered) { - Intent intent = new Intent(); - intent.putExtra(CropExtras.KEY_CROPPED_RECT, mImageShow.getImageCropBounds()); - if (mSaveToExtraUri) { - mImageShow.saveToUri(filtered, mCropExtras.getExtraOutput(), - mCropExtras.getOutputFormat(), this); - } - if (mSaveAsWallpaper) { - setWallpaperInBackground(filtered); - } - if (mReturnAsExtra) { - if (filtered != null) { - int bmapSize = filtered.getRowBytes() * filtered.getHeight(); - /* - * Max size of Binder transaction buffer is 1Mb, so constrain - * Bitmap to be somewhat less than this, otherwise we get - * TransactionTooLargeExceptions. - */ - if (bmapSize > MAX_BMAP_IN_INTENT) { - Log.w(LOGTAG, "Bitmap too large to be returned via intent"); - } else { - intent.putExtra(CropExtras.KEY_DATA, filtered); - } - } - } - setResult(RESULT_OK, intent); - if (!mSaveToExtraUri) { + if (mImageShow.hasModifications()) { + // Get the name of the album, to which the image will be saved + File saveDir = SaveCopyTask.getFinalSaveDirectory(this, mImageLoader.getUri()); + int bucketId = GalleryUtils.getBucketId(saveDir.getPath()); + String albumName = LocalAlbum.getLocalizedName(getResources(), bucketId, null); + showSavingProgress(albumName); + mImageShow.saveImage(this, null); + } else { done(); } } - 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(); - } + hideSavingProgress(); finish(); } @@ -1054,4 +980,13 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL System.loadLibrary("jni_filtershow_filters"); } + private void extractXMPData() { + XMresults res = XmpPresets.extractXMPData( + getBaseContext(), mMasterImage, getIntent().getData()); + if (res == null) + return; + + mOriginalImageUri = res.originalimage; + mOriginalPreset = res.preset; + } } diff --git a/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java b/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java index 8760c4a09..1ea40f202 100644 --- a/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java +++ b/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java @@ -29,8 +29,9 @@ import com.android.gallery3d.filtershow.imageshow.GeometryMetadata; import com.android.gallery3d.filtershow.imageshow.MasterImage; import com.android.gallery3d.filtershow.presets.FilterEnvironment; import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.presets.PipelineInterface; -public class CachingPipeline { +public class CachingPipeline implements PipelineInterface { private static final String LOGTAG = "CachingPipeline"; private boolean DEBUG = false; @@ -65,22 +66,10 @@ public class CachingPipeline { mName = name; } - public static synchronized Resources getResources() { - return sResources; - } - - public static synchronized void setResources(Resources resources) { - sResources = resources; - } - public static synchronized RenderScript getRenderScriptContext() { return sRS; } - public static synchronized void setRenderScriptContext(RenderScript RS) { - sRS = RS; - } - public static synchronized void createRenderscriptContext(Activity context) { if (sRS != null) { Log.w(LOGTAG, "A prior RS context exists when calling setRenderScriptContext"); @@ -128,6 +117,10 @@ public class CachingPipeline { } } + public Resources getResources() { + return sRS.getApplicationContext().getResources(); + } + private synchronized void destroyPixelAllocations() { if (DEBUG) { Log.v(LOGTAG, "destroyPixelAllocations in " + getName()); @@ -167,14 +160,14 @@ public class CachingPipeline { } private void setupEnvironment(ImagePreset preset, boolean highResPreview) { - mEnvironment.setCachingPipeline(this); + mEnvironment.setPipeline(this); mEnvironment.setFiltersManager(mFiltersManager); if (highResPreview) { mEnvironment.setScaleFactor(mHighResPreviewScaleFactor); } else { mEnvironment.setScaleFactor(mPreviewScaleFactor); } - mEnvironment.setQuality(ImagePreset.QUALITY_PREVIEW); + mEnvironment.setQuality(FilterEnvironment.QUALITY_PREVIEW); mEnvironment.setImagePreset(preset); mEnvironment.setStop(false); } @@ -293,11 +286,11 @@ public class CachingPipeline { || request.getType() == RenderingRequest.STYLE_ICON_RENDERING) { if (request.getType() == RenderingRequest.ICON_RENDERING) { - mEnvironment.setQuality(ImagePreset.QUALITY_ICON); + mEnvironment.setQuality(FilterEnvironment.QUALITY_ICON); } else if (request.getType() == RenderingRequest.STYLE_ICON_RENDERING) { mEnvironment.setQuality(ImagePreset.STYLE_ICON); } else { - mEnvironment.setQuality(ImagePreset.QUALITY_PREVIEW); + mEnvironment.setQuality(FilterEnvironment.QUALITY_PREVIEW); } Bitmap bmp = preset.apply(bitmap, mEnvironment); @@ -317,8 +310,11 @@ public class CachingPipeline { setupEnvironment(preset, false); mFiltersManager.freeFilterResources(preset); preset.applyFilters(-1, -1, in, out, mEnvironment); - // TODO: we should render the border onto a different bitmap instead - preset.applyBorder(in, out, mEnvironment); + boolean copyOut = false; + if (preset.nbFilters() > 0) { + copyOut = true; + } + preset.applyBorder(in, out, copyOut, mEnvironment); } } @@ -328,7 +324,7 @@ public class CachingPipeline { return bitmap; } setupEnvironment(preset, false); - mEnvironment.setQuality(ImagePreset.QUALITY_FINAL); + mEnvironment.setQuality(FilterEnvironment.QUALITY_FINAL); mEnvironment.setScaleFactor(1.0f); mFiltersManager.freeFilterResources(preset); bitmap = preset.applyGeometry(bitmap, mEnvironment); @@ -345,7 +341,7 @@ public class CachingPipeline { } mGeometry.useRepresentation(preset.getGeometry()); return mGeometry.apply(bitmap, mPreviewScaleFactor, - ImagePreset.QUALITY_PREVIEW); + FilterEnvironment.QUALITY_PREVIEW); } public synchronized void compute(TripleBufferBitmap buffer, ImagePreset preset, int type) { @@ -458,4 +454,7 @@ public class CachingPipeline { return mName; } + public RenderScript getRSContext() { + return CachingPipeline.getRenderScriptContext(); + } } diff --git a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java index b4e98e114..7ddd9bebe 100644 --- a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java +++ b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java @@ -22,12 +22,10 @@ import android.content.res.Resources; import android.database.Cursor; import android.database.sqlite.SQLiteException; import android.graphics.Bitmap; -import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; import android.graphics.BitmapRegionDecoder; import android.graphics.Matrix; import android.graphics.Rect; -import android.graphics.Bitmap.CompressFormat; import android.net.Uri; import android.provider.MediaStore; import android.util.Log; @@ -36,27 +34,19 @@ import com.adobe.xmp.XMPException; import com.adobe.xmp.XMPMeta; import com.android.gallery3d.R; import com.android.gallery3d.common.Utils; -import com.android.gallery3d.exif.ExifTag; import com.android.gallery3d.exif.ExifInterface; import com.android.gallery3d.filtershow.FilterShowActivity; import com.android.gallery3d.filtershow.HistoryAdapter; -import com.android.gallery3d.filtershow.filters.FiltersManager; import com.android.gallery3d.filtershow.imageshow.ImageShow; import com.android.gallery3d.filtershow.imageshow.MasterImage; import com.android.gallery3d.filtershow.presets.ImagePreset; -import com.android.gallery3d.filtershow.tools.BitmapTask; import com.android.gallery3d.filtershow.tools.SaveCopyTask; -import com.android.gallery3d.util.InterruptableOutputStream; import com.android.gallery3d.util.XmpUtilHelper; -import java.io.ByteArrayInputStream; -import java.io.Closeable; import java.io.File; -import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.util.Vector; import java.util.concurrent.locks.ReentrantLock; @@ -71,8 +61,6 @@ public class ImageLoader { private Bitmap mOriginalBitmapHighres = null; private Bitmap mBackgroundBitmap = null; - private final ZoomCache mZoomCache = new ZoomCache(); - private int mOrientation = 0; private HistoryAdapter mAdapter = null; @@ -511,116 +499,6 @@ public class ImageLoader { return bmap; } - public void returnFilteredResult(ImagePreset preset, - final FilterShowActivity filterShowActivity) { - BitmapTask.Callbacks<ImagePreset> cb = new BitmapTask.Callbacks<ImagePreset>() { - - @Override - public void onComplete(Bitmap result) { - filterShowActivity.onFilteredResult(result); - } - - @Override - public void onCancel() { - } - - @Override - public Bitmap onExecute(ImagePreset param) { - if (param == null || mUri == null) { - return null; - } - BitmapFactory.Options options = new BitmapFactory.Options(); - boolean noBitmap = true; - int num_tries = 0; - if (options.inSampleSize < 1) { - options.inSampleSize = 1; - } - 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; - } - CachingPipeline pipeline = new CachingPipeline( - FiltersManager.getManager(), "Saving"); - bitmap = pipeline.renderFinalImage(bitmap, param); - 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; - } - }; - - (new BitmapTask<ImagePreset>(cb)).execute(preset); - } - - private String getFileExtension(String requestFormat) { - String outputFormat = (requestFormat == null) - ? "jpg" - : requestFormat; - outputFormat = outputFormat.toLowerCase(); - return (outputFormat.equals("png") || outputFormat.equals("gif")) - ? "png" // We don't support gif compression. - : "jpg"; - } - - private CompressFormat convertExtensionToCompressFormat(String extension) { - return extension.equals("png") ? CompressFormat.PNG : CompressFormat.JPEG; - } - - public void saveToUri(Bitmap bmap, Uri uri, final String outputFormat, - final FilterShowActivity filterShowActivity) { - - OutputStream out = null; - try { - out = filterShowActivity.getContentResolver().openOutputStream(uri); - } catch (FileNotFoundException e) { - Log.w(LOGTAG, "cannot write output", e); - out = null; - } finally { - if (bmap == null || out == null) { - return; - } - } - - final InterruptableOutputStream ios = new InterruptableOutputStream(out); - - BitmapTask.Callbacks<Bitmap> cb = new BitmapTask.Callbacks<Bitmap>() { - - @Override - public void onComplete(Bitmap result) { - filterShowActivity.done(); - } - - @Override - public void onCancel() { - ios.interrupt(); - } - - @Override - public Bitmap onExecute(Bitmap param) { - CompressFormat cf = convertExtensionToCompressFormat(getFileExtension(outputFormat)); - param.compress(cf, DEFAULT_COMPRESS_QUALITY, ios); - Utils.closeSilently(ios); - return null; - } - }; - - (new BitmapTask<Bitmap>(cb)).execute(bmap); - } - public void setAdapter(HistoryAdapter adapter) { mAdapter = adapter; } diff --git a/src/com/android/gallery3d/filtershow/cache/ZoomCache.java b/src/com/android/gallery3d/filtershow/cache/ZoomCache.java deleted file mode 100644 index dbd0751ac..000000000 --- a/src/com/android/gallery3d/filtershow/cache/ZoomCache.java +++ /dev/null @@ -1,55 +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.cache; - -import android.graphics.Bitmap; -import android.graphics.Rect; - -import com.android.gallery3d.filtershow.presets.ImagePreset; - -public class ZoomCache { - - private ImagePreset mImagePreset = null; - private Bitmap mBitmap = null; - private Rect mBounds = null; - - // TODO: move the processing to a background thread... - public Bitmap getImage(ImagePreset preset, Rect bounds) { - if (mBounds != bounds) { - return null; - } - if (mImagePreset == null) { - return null; - } - if (!mImagePreset.same(preset)) { - return null; - } - return mBitmap; - } - - public void setImage(ImagePreset preset, Rect bounds, Bitmap bitmap) { - mBitmap = bitmap; - mBounds = bounds; - mImagePreset = preset; - } - - public void reset(ImagePreset imagePreset) { - if (imagePreset == mImagePreset) { - mBitmap = null; - } - } -} diff --git a/src/com/android/gallery3d/filtershow/controller/BasicParameterStyle.java b/src/com/android/gallery3d/filtershow/controller/BasicParameterStyle.java index 072edd72a..25169c2d8 100644 --- a/src/com/android/gallery3d/filtershow/controller/BasicParameterStyle.java +++ b/src/com/android/gallery3d/filtershow/controller/BasicParameterStyle.java @@ -109,5 +109,4 @@ public class BasicParameterStyle implements ParameterStyles { public void setFilterView(FilterView editor) { mEditor = editor; } - } diff --git a/src/com/android/gallery3d/filtershow/controller/BasicSlider.java b/src/com/android/gallery3d/filtershow/controller/BasicSlider.java index df5b6ae73..9d8278d52 100644 --- a/src/com/android/gallery3d/filtershow/controller/BasicSlider.java +++ b/src/com/android/gallery3d/filtershow/controller/BasicSlider.java @@ -84,5 +84,4 @@ public class BasicSlider implements Control { mSeekBar.setMax(mParameter.getMaximum() - mParameter.getMinimum()); mSeekBar.setProgress(mParameter.getValue() - mParameter.getMinimum()); } - } diff --git a/src/com/android/gallery3d/filtershow/crop/CropMath.java b/src/com/android/gallery3d/filtershow/crop/CropMath.java index 849ac60ef..671554f16 100644 --- a/src/com/android/gallery3d/filtershow/crop/CropMath.java +++ b/src/com/android/gallery3d/filtershow/crop/CropMath.java @@ -196,14 +196,13 @@ public class CropMath { float finalH = origH; if (origA < a) { finalH = origW / a; + r.top = r.centerY() - finalH / 2; + r.bottom = r.top + finalH; } else { finalW = origH * a; + r.left = r.centerX() - finalW / 2; + r.right = r.left + finalW; } - float centX = r.centerX(); - float centY = r.centerY(); - float hw = finalW / 2; - float hh = finalH / 2; - r.set(centX - hw, centY - hh, centX + hw, centY + hh); } /** diff --git a/src/com/android/gallery3d/filtershow/data/FilterStackDBHelper.java b/src/com/android/gallery3d/filtershow/data/FilterStackDBHelper.java new file mode 100644 index 000000000..e18d3104f --- /dev/null +++ b/src/com/android/gallery3d/filtershow/data/FilterStackDBHelper.java @@ -0,0 +1,101 @@ +/* + * 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.data; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; + +public class FilterStackDBHelper extends SQLiteOpenHelper { + + public static final int DATABASE_VERSION = 1; + public static final String DATABASE_NAME = "filterstacks.db"; + private static final String SQL_CREATE_TABLE = "CREATE TABLE "; + + public static interface FilterStack { + /** The row uid */ + public static final String _ID = "_id"; + /** The table name */ + public static final String TABLE = "filterstack"; + /** The stack name */ + public static final String STACK_ID = "stack_id"; + /** A serialized stack of filters. */ + public static final String FILTER_STACK= "stack"; + } + + private static final String[][] CREATE_FILTER_STACK = { + { FilterStack._ID, "INTEGER PRIMARY KEY AUTOINCREMENT" }, + { FilterStack.STACK_ID, "TEXT" }, + { FilterStack.FILTER_STACK, "BLOB" }, + }; + + public FilterStackDBHelper(Context context, String name, int version) { + super(context, name, null, version); + } + + public FilterStackDBHelper(Context context, String name) { + this(context, name, DATABASE_VERSION); + } + + public FilterStackDBHelper(Context context) { + this(context, DATABASE_NAME); + } + + @Override + public void onCreate(SQLiteDatabase db) { + createTable(db, FilterStack.TABLE, CREATE_FILTER_STACK); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + dropTable(db, FilterStack.TABLE); + onCreate(db); + } + + protected static void createTable(SQLiteDatabase db, String table, String[][] columns) { + StringBuilder create = new StringBuilder(SQL_CREATE_TABLE); + create.append(table).append('('); + boolean first = true; + for (String[] column : columns) { + if (!first) { + create.append(','); + } + first = false; + for (String val : column) { + create.append(val).append(' '); + } + } + create.append(')'); + db.beginTransaction(); + try { + db.execSQL(create.toString()); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + } + + protected static void dropTable(SQLiteDatabase db, String table) { + db.beginTransaction(); + try { + db.execSQL("drop table if exists " + table); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + } +} diff --git a/src/com/android/gallery3d/filtershow/data/FilterStackSource.java b/src/com/android/gallery3d/filtershow/data/FilterStackSource.java new file mode 100644 index 000000000..4e343777d --- /dev/null +++ b/src/com/android/gallery3d/filtershow/data/FilterStackSource.java @@ -0,0 +1,143 @@ +/* + * 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.data; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteException; +import android.util.Log; +import android.util.Pair; + +import com.android.gallery3d.filtershow.data.FilterStackDBHelper.FilterStack; + +import java.util.ArrayList; +import java.util.List; + +public class FilterStackSource { + private static final String LOGTAG = "FilterStackSource"; + + private SQLiteDatabase database = null;; + private final FilterStackDBHelper dbHelper; + + public FilterStackSource(Context context) { + dbHelper = new FilterStackDBHelper(context); + } + + public void open() { + try { + database = dbHelper.getWritableDatabase(); + } catch (SQLiteException e) { + Log.w(LOGTAG, "could not open database", e); + } + } + + public void close() { + database = null; + dbHelper.close(); + } + + public boolean insertStack(String stackName, byte[] stackBlob) { + boolean ret = true; + ContentValues val = new ContentValues(); + val.put(FilterStack.STACK_ID, stackName); + val.put(FilterStack.FILTER_STACK, stackBlob); + database.beginTransaction(); + try { + ret = (-1 != database.insert(FilterStack.TABLE, null, val)); + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + } + return ret; + } + + public boolean removeStack(String stackName) { + boolean ret = true; + database.beginTransaction(); + try { + ret = (0 != database.delete(FilterStack.TABLE, FilterStack.STACK_ID + " = ?", + new String[] { stackName})); + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + } + return ret; + } + + public void removeAllStacks() { + database.beginTransaction(); + try { + database.delete(FilterStack.TABLE, null, null); + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + } + } + + public byte[] getStack(String stackName) { + byte[] ret = null; + Cursor c = null; + database.beginTransaction(); + try { + c = database.query(FilterStack.TABLE, + new String[] { FilterStack.FILTER_STACK }, + FilterStack.STACK_ID + " = ?", + new String[] { stackName }, null, null, null, null); + if (c != null && c.moveToFirst() && !c.isNull(0)) { + ret = c.getBlob(0); + } + database.setTransactionSuccessful(); + } finally { + if (c != null) { + c.close(); + } + database.endTransaction(); + } + return ret; + } + + public List<Pair<String, byte[]>> getAllStacks() { + List<Pair<String, byte[]>> ret = new ArrayList<Pair<String, byte[]>>(); + Cursor c = null; + database.beginTransaction(); + try { + c = database.query(FilterStack.TABLE, + new String[] { FilterStack.STACK_ID, FilterStack.FILTER_STACK }, + null, null, null, null, null, null); + if (c != null) { + boolean loopCheck = c.moveToFirst(); + while (loopCheck) { + String name = (c.isNull(0)) ? null : c.getString(0); + byte[] b = (c.isNull(1)) ? null : c.getBlob(1); + ret.add(new Pair<String, byte[]>(name, b)); + loopCheck = c.moveToNext(); + } + } + database.setTransactionSuccessful(); + } finally { + if (c != null) { + c.close(); + } + database.endTransaction(); + } + if (ret.size() <= 0) { + return null; + } + return ret; + } +} diff --git a/src/com/android/gallery3d/filtershow/editors/Editor.java b/src/com/android/gallery3d/filtershow/editors/Editor.java index 02bbcde4d..5d9755c8b 100644 --- a/src/com/android/gallery3d/filtershow/editors/Editor.java +++ b/src/com/android/gallery3d/filtershow/editors/Editor.java @@ -290,8 +290,5 @@ public class Editor implements OnSeekBarChangeListener, SwapButton.SwapButtonLis } public void detach() { - if (mImageShow != null) { - mImageShow.unselect(); - } } } diff --git a/src/com/android/gallery3d/filtershow/editors/EditorPanel.java b/src/com/android/gallery3d/filtershow/editors/EditorPanel.java index e35bc8fb3..d06f30fe8 100644 --- a/src/com/android/gallery3d/filtershow/editors/EditorPanel.java +++ b/src/com/android/gallery3d/filtershow/editors/EditorPanel.java @@ -102,7 +102,6 @@ public class EditorPanel extends Fragment { mEditor = activity.getEditor(mEditorID); if (mEditor != null) { mEditor.setUpEditorUI(actionControl, editControl, editTitle, toggleState); - mEditor.getImageShow().select(); mEditor.reflectCurrentFilter(); if (mEditor.useUtilityPanel()) { mEditor.openUtilityPanel((LinearLayout) actionControl); diff --git a/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java b/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java index 9927a0a5e..4186b9337 100644 --- a/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java +++ b/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java @@ -17,6 +17,7 @@ package com.android.gallery3d.filtershow.filters; import android.content.Context; import android.content.res.Resources; +import android.util.Log; import com.android.gallery3d.R; import com.android.gallery3d.filtershow.presets.ImagePreset; @@ -24,11 +25,14 @@ import com.android.gallery3d.filtershow.presets.ImagePreset; import java.util.HashMap; import java.util.Vector; -public abstract class BaseFiltersManager { +public abstract class BaseFiltersManager implements FiltersManagerInterface { protected HashMap<Class, ImageFilter> mFilters = null; + protected HashMap<String, FilterRepresentation> mRepresentationLookup = null; + private static final String LOGTAG = "BaseFiltersManager"; protected void init() { mFilters = new HashMap<Class, ImageFilter>(); + mRepresentationLookup = new HashMap<String, FilterRepresentation>(); Vector<Class> filters = new Vector<Class>(); addFilterClasses(filters); for (Class filterClass : filters) { @@ -36,6 +40,12 @@ public abstract class BaseFiltersManager { Object filterInstance = filterClass.newInstance(); if (filterInstance instanceof ImageFilter) { mFilters.put(filterClass, (ImageFilter) filterInstance); + + FilterRepresentation rep = + ((ImageFilter) filterInstance).getDefaultRepresentation(); + if (rep != null) { + addRepresentation(rep); + } } } catch (InstantiationException e) { e.printStackTrace(); @@ -45,18 +55,29 @@ public abstract class BaseFiltersManager { } } + public void addRepresentation(FilterRepresentation rep) { + mRepresentationLookup.put(rep.getSerializationName(), rep); + } + + public FilterRepresentation createFilterFromName(String name) { + try { + return mRepresentationLookup.get(name).clone(); + } catch (Exception e) { + Log.v(LOGTAG, "unable to generate a filter representation for \"" + name + "\""); + e.printStackTrace(); + } + return null; + } + public ImageFilter getFilter(Class c) { return mFilters.get(c); } + @Override public ImageFilter getFilterForRepresentation(FilterRepresentation representation) { return mFilters.get(representation.getFilterClass()); } - public void addFilter(Class filterClass, ImageFilter filter) { - mFilters.put(filterClass, filter); - } - public FilterRepresentation getRepresentation(Class c) { ImageFilter filter = mFilters.get(c); if (filter != null) { @@ -89,7 +110,7 @@ public abstract class BaseFiltersManager { protected void addFilterClasses(Vector<Class> filters) { filters.add(ImageFilterTinyPlanet.class); - //filters.add(ImageFilterRedEye.class); + filters.add(ImageFilterRedEye.class); filters.add(ImageFilterWBalance.class); filters.add(ImageFilterExposure.class); filters.add(ImageFilterVignette.class); @@ -99,7 +120,7 @@ public abstract class BaseFiltersManager { filters.add(ImageFilterVibrance.class); filters.add(ImageFilterSharpen.class); filters.add(ImageFilterCurves.class); - // filters.add(ImageFilterDraw.class); + filters.add(ImageFilterDraw.class); filters.add(ImageFilterHue.class); filters.add(ImageFilterSaturated.class); filters.add(ImageFilterBwFilter.class); @@ -145,6 +166,7 @@ public abstract class BaseFiltersManager { FilterFxRepresentation fx = new FilterFxRepresentation( context.getString(fxNameid[i]), drawid[i], fxNameid[i]); representations.add(fx); + addRepresentation(fx); } } @@ -168,8 +190,8 @@ public abstract class BaseFiltersManager { } public void addTools(Vector<FilterRepresentation> representations) { - //representations.add(getRepresentation(ImageFilterRedEye.class)); - // representations.add(getRepresentation(ImageFilterDraw.class)); + representations.add(getRepresentation(ImageFilterRedEye.class)); + representations.add(getRepresentation(ImageFilterDraw.class)); } public void setFilterResources(Resources resources) { diff --git a/src/com/android/gallery3d/filtershow/filters/FilterBasicRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterBasicRepresentation.java index 4d0651edb..368e5c029 100644 --- a/src/com/android/gallery3d/filtershow/filters/FilterBasicRepresentation.java +++ b/src/com/android/gallery3d/filtershow/filters/FilterBasicRepresentation.java @@ -31,6 +31,8 @@ public class FilterBasicRepresentation extends FilterRepresentation implements P private int mMaximum; private int mDefaultValue; private int mPreviewValue; + public static final String SERIAL_NAME = "Name"; + public static final String SERIAL_VALUE = "Value"; private boolean mLogVerbose = Log.isLoggable(LOGTAG, Log.VERBOSE); public FilterBasicRepresentation(String name, int minimum, int value, int maximum) { @@ -171,4 +173,23 @@ public class FilterBasicRepresentation extends FilterRepresentation implements P public void copyFrom(Parameter src) { useParametersFrom((FilterBasicRepresentation) src); } + + @Override + public String[][] serializeRepresentation() { + String[][] ret = { + {SERIAL_NAME , getName() }, + {SERIAL_VALUE , Integer.toString(mValue)}}; + return ret; + } + + @Override + public void deSerializeRepresentation(String[][] rep) { + super.deSerializeRepresentation(rep); + for (int i = 0; i < rep.length; i++) { + if (SERIAL_VALUE.equals(rep[i][0])) { + mValue = Integer.parseInt(rep[i][1]); + break; + } + } + } } diff --git a/src/com/android/gallery3d/filtershow/filters/FilterCurvesRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterCurvesRepresentation.java index cbcae4b37..a32068aeb 100644 --- a/src/com/android/gallery3d/filtershow/filters/FilterCurvesRepresentation.java +++ b/src/com/android/gallery3d/filtershow/filters/FilterCurvesRepresentation.java @@ -15,6 +15,7 @@ public class FilterCurvesRepresentation extends FilterRepresentation { public FilterCurvesRepresentation() { super("Curves"); + setSerializationName("CURVES"); setFilterClass(ImageFilterCurves.class); setTextId(R.string.curvesRGB); setButtonId(R.id.curvesButtonRGB); diff --git a/src/com/android/gallery3d/filtershow/filters/FilterDrawRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterDrawRepresentation.java index dc59b0cfc..9b144b9e9 100644 --- a/src/com/android/gallery3d/filtershow/filters/FilterDrawRepresentation.java +++ b/src/com/android/gallery3d/filtershow/filters/FilterDrawRepresentation.java @@ -49,6 +49,7 @@ public class FilterDrawRepresentation extends FilterRepresentation { public FilterDrawRepresentation() { super("Draw"); + setSerializationName("DRAW"); setFilterClass(ImageFilterDraw.class); setPriority(FilterRepresentation.TYPE_VIGNETTE); setTextId(R.string.imageDraw); diff --git a/src/com/android/gallery3d/filtershow/filters/FilterFxRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterFxRepresentation.java index 6e2e7ea16..d0ba302c7 100644 --- a/src/com/android/gallery3d/filtershow/filters/FilterFxRepresentation.java +++ b/src/com/android/gallery3d/filtershow/filters/FilterFxRepresentation.java @@ -16,12 +16,11 @@ package com.android.gallery3d.filtershow.filters; -import android.graphics.Bitmap; -import com.android.gallery3d.app.Log; import com.android.gallery3d.filtershow.editors.ImageOnlyEditor; public class FilterFxRepresentation extends FilterRepresentation { - private static final String LOGTAG = "FilterFxRepresentation"; + private static final String SERIALIZATION_NAME = "LUT3D"; + private static final String LOGTAG = "FilterFxRepresentation"; // TODO: When implementing serialization, we should find a unique way of // specifying bitmaps / names (the resource IDs being random) private int mBitmapResource = 0; @@ -29,6 +28,8 @@ public class FilterFxRepresentation extends FilterRepresentation { public FilterFxRepresentation(String name, int bitmapResource, int nameResource) { super(name); + setSerializationName(SERIALIZATION_NAME + "_" + name); + mBitmapResource = bitmapResource; mNameResource = nameResource; setFilterClass(ImageFilterFx.class); @@ -41,6 +42,7 @@ public class FilterFxRepresentation extends FilterRepresentation { setSupportsPartialRendering(true); } + @Override public String toString() { return "FilterFx: " + hashCode() + " : " + getName() + " bitmap rsc: " + mBitmapResource; } @@ -54,6 +56,7 @@ public class FilterFxRepresentation extends FilterRepresentation { return representation; } + @Override public synchronized void useParametersFrom(FilterRepresentation a) { if (a instanceof FilterFxRepresentation) { FilterFxRepresentation representation = (FilterFxRepresentation) a; @@ -78,6 +81,7 @@ public class FilterFxRepresentation extends FilterRepresentation { return false; } + @Override public boolean same(FilterRepresentation representation) { if (!super.same(representation)) { return false; @@ -85,6 +89,7 @@ public class FilterFxRepresentation extends FilterRepresentation { return equals(representation); } + @Override public boolean allowsMultipleInstances() { return true; } diff --git a/src/com/android/gallery3d/filtershow/filters/FilterRedEyeRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterRedEyeRepresentation.java index 3f823ea1e..8a878415c 100644 --- a/src/com/android/gallery3d/filtershow/filters/FilterRedEyeRepresentation.java +++ b/src/com/android/gallery3d/filtershow/filters/FilterRedEyeRepresentation.java @@ -28,6 +28,7 @@ public class FilterRedEyeRepresentation extends FilterPointRepresentation { public FilterRedEyeRepresentation() { super("RedEye",R.string.redeye,EditorRedEye.ID); + setSerializationName("REDEYE"); setFilterClass(ImageFilterRedEye.class); setOverlayId(R.drawable.photoeditor_effect_redeye); setOverlayOnly(true); diff --git a/src/com/android/gallery3d/filtershow/filters/FilterRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterRepresentation.java index 82012b992..3bb60bb74 100644 --- a/src/com/android/gallery3d/filtershow/filters/FilterRepresentation.java +++ b/src/com/android/gallery3d/filtershow/filters/FilterRepresentation.java @@ -16,7 +16,7 @@ package com.android.gallery3d.filtershow.filters; -import com.android.gallery3d.app.Log; +import android.util.Log; import com.android.gallery3d.filtershow.editors.BasicEditor; public class FilterRepresentation implements Cloneable { @@ -34,7 +34,7 @@ public class FilterRepresentation implements Cloneable { private boolean mShowEditingControls = true; private boolean mShowParameterValue = true; private boolean mShowUtilityPanel = true; - + private String mSerializationName; public static final byte TYPE_BORDER = 1; public static final byte TYPE_FX = 2; public static final byte TYPE_WBALANCE = 3; @@ -63,6 +63,8 @@ public class FilterRepresentation implements Cloneable { representation.setShowEditingControls(showEditingControls()); representation.setShowParameterValue(showParameterValue()); representation.setShowUtilityPanel(showUtilityPanel()); + representation.mSerializationName = mSerializationName; + representation.mTempRepresentation = mTempRepresentation != null ? mTempRepresentation.clone() : null; if (DEBUG) { @@ -96,6 +98,10 @@ public class FilterRepresentation implements Cloneable { return mName; } + public void setScrName(String name) { + mName = name; + } + public void setName(String name) { mName = name; } @@ -104,6 +110,14 @@ public class FilterRepresentation implements Cloneable { return mName; } + public void setSerializationName(String sname) { + mSerializationName = sname; + } + + public String getSerializationName() { + return mSerializationName; + } + public void setPriority(int priority) { mPriority = priority; } @@ -241,4 +255,22 @@ public class FilterRepresentation implements Cloneable { return ""; } + public String[][] serializeRepresentation() { + String[][] ret = { { "Name" , getName() }}; + return ret; + } + + public void deSerializeRepresentation(String[][] rep) { + for (int i = 0; i < rep.length; i++) { + if ("Name".equals(rep[i][0])) { + mName = rep[i][0]; + break; + } + } + } + + // Override this in subclasses + public int getStyle() { + return -1; + } } diff --git a/src/com/android/gallery3d/filtershow/filters/FilterTinyPlanetRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterTinyPlanetRepresentation.java index ac5e04601..48c8b380e 100644 --- a/src/com/android/gallery3d/filtershow/filters/FilterTinyPlanetRepresentation.java +++ b/src/com/android/gallery3d/filtershow/filters/FilterTinyPlanetRepresentation.java @@ -20,11 +20,14 @@ import com.android.gallery3d.R; import com.android.gallery3d.filtershow.editors.EditorTinyPlanet; public class FilterTinyPlanetRepresentation extends FilterBasicRepresentation { + private static final String SERIALIZATION_NAME = "TINYPLANET"; private static final String LOGTAG = "FilterTinyPlanetRepresentation"; + private static final String SERIAL_ANGLE = "Angle"; private float mAngle = 0; public FilterTinyPlanetRepresentation() { super("TinyPlanet", 0, 50, 100); + setSerializationName(SERIALIZATION_NAME); setShowParameterValue(true); setFilterClass(ImageFilterTinyPlanet.class); setPriority(FilterRepresentation.TYPE_TINYPLANET); @@ -71,4 +74,25 @@ public class FilterTinyPlanetRepresentation extends FilterBasicRepresentation { // TinyPlanet always has an effect return false; } + + @Override + public String[][] serializeRepresentation() { + String[][] ret = { + {SERIAL_NAME , getName() }, + {SERIAL_VALUE , Integer.toString(getValue())}, + {SERIAL_ANGLE , Float.toString(mAngle)}}; + return ret; + } + + @Override + public void deSerializeRepresentation(String[][] rep) { + super.deSerializeRepresentation(rep); + for (int i = 0; i < rep.length; i++) { + if (SERIAL_VALUE.equals(rep[i][0])) { + setValue(Integer.parseInt(rep[i][1])); + } else if (SERIAL_ANGLE.equals(rep[i][0])) { + setAngle(Float.parseFloat(rep[i][1])); + } + } + } } diff --git a/src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java index eef54ef58..9827088ff 100644 --- a/src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java +++ b/src/com/android/gallery3d/filtershow/filters/FilterVignetteRepresentation.java @@ -29,6 +29,7 @@ public class FilterVignetteRepresentation extends FilterBasicRepresentation impl public FilterVignetteRepresentation() { super("Vignette", -100, 50, 100); + setSerializationName("VIGNETTE"); setShowParameterValue(true); setPriority(FilterRepresentation.TYPE_VIGNETTE); setTextId(R.string.vignette); @@ -111,4 +112,44 @@ public class FilterVignetteRepresentation extends FilterBasicRepresentation impl public boolean isNil() { return getValue() == 0; } + + private static final String[] sParams = { + "Name", "value", "mCenterX", "mCenterY", "mRadiusX", + "mRadiusY" + }; + + @Override + public String[][] serializeRepresentation() { + String[][] ret = { + { sParams[0], getName() }, + { sParams[1], Integer.toString(getValue()) }, + { sParams[2], Float.toString(mCenterX) }, + { sParams[3], Float.toString(mCenterY) }, + { sParams[4], Float.toString(mRadiusX) }, + { sParams[5], Float.toString(mRadiusY) } + }; + return ret; + } + + @Override + public void deSerializeRepresentation(String[][] rep) { + super.deSerializeRepresentation(rep); + for (int i = 0; i < rep.length; i++) { + String key = rep[i][0]; + String value = rep[i][1]; + if (sParams[0].equals(key)) { + setName(value); + } else if (sParams[1].equals(key)) { + setValue(Integer.parseInt(value)); + } else if (sParams[2].equals(key)) { + mCenterX = Float.parseFloat(value); + } else if (sParams[3].equals(key)) { + mCenterY = Float.parseFloat(value); + } else if (sParams[4].equals(key)) { + mRadiusX = Float.parseFloat(value); + } else if (sParams[5].equals(key)) { + mRadiusY = Float.parseFloat(value); + } + } + } } diff --git a/src/com/android/gallery3d/filtershow/filters/FiltersManagerInterface.java b/src/com/android/gallery3d/filtershow/filters/FiltersManagerInterface.java new file mode 100644 index 000000000..710128f99 --- /dev/null +++ b/src/com/android/gallery3d/filtershow/filters/FiltersManagerInterface.java @@ -0,0 +1,21 @@ +/* + * 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; + +public interface FiltersManagerInterface { + ImageFilter getFilterForRepresentation(FilterRepresentation representation); +} diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilter.java b/src/com/android/gallery3d/filtershow/filters/ImageFilter.java index 96ab84f9d..6481e108e 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilter.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilter.java @@ -16,12 +16,12 @@ package com.android.gallery3d.filtershow.filters; +import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Matrix; import android.support.v8.renderscript.Allocation; import android.widget.Toast; -import com.android.gallery3d.filtershow.FilterShowActivity; import com.android.gallery3d.filtershow.imageshow.GeometryMetadata; import com.android.gallery3d.filtershow.presets.FilterEnvironment; import com.android.gallery3d.filtershow.presets.ImagePreset; @@ -35,9 +35,9 @@ public abstract class ImageFilter implements Cloneable { // TODO: Temporary, for dogfood note memory issues with toasts for better // feedback. Remove this when filters actually work in low memory // situations. - private static FilterShowActivity sActivity = null; + private static Activity sActivity = null; - public static void setActivityForMemoryToasts(FilterShowActivity activity) { + public static void setActivityForMemoryToasts(Activity activity) { sActivity = activity; } @@ -69,17 +69,15 @@ public abstract class ImageFilter implements Cloneable { public boolean supportsAllocationInput() { return false; } public void apply(Allocation in, Allocation out) { + setGeneralParameters(); } public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) { // do nothing here, subclasses will implement filtering here + setGeneralParameters(); return bitmap; } - public ImagePreset getImagePreset() { - return getEnvironment().getImagePreset(); - } - public abstract void useRepresentation(FilterRepresentation representation); native protected void nativeApplyGradientFilter(Bitmap bitmap, int w, int h, @@ -90,10 +88,11 @@ public abstract class ImageFilter implements Cloneable { } protected Matrix getOriginalToScreenMatrix(int w, int h) { - GeometryMetadata geo = getImagePreset().mGeoData; + ImagePreset preset = getEnvironment().getImagePreset(); + GeometryMetadata geo = getEnvironment().getImagePreset().mGeoData; Matrix originalToScreen = geo.getOriginalToScreen(true, - getImagePreset().getImageLoader().getOriginalBounds().width(), - getImagePreset().getImageLoader().getOriginalBounds().height(), + preset.getImageLoader().getOriginalBounds().width(), + preset.getImageLoader().getOriginalBounds().height(), w, h); return originalToScreen; } @@ -105,4 +104,11 @@ public abstract class ImageFilter implements Cloneable { public FilterEnvironment getEnvironment() { return mEnvironment; } + + public void setGeneralParameters() { + // should implement in subclass which like to transport + // some information to other filters. (like the style setting from RetroLux + // and Film to FixedFrame) + mEnvironment.clearGeneralParameters(); + } } diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterBwFilter.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterBwFilter.java index a4626cdb2..64c48dffa 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterBwFilter.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterBwFilter.java @@ -23,6 +23,7 @@ import android.graphics.Color; public class ImageFilterBwFilter extends SimpleImageFilter { + private static final String SERIALIZATION_NAME = "BWFILTER"; public ImageFilterBwFilter() { mName = "BW Filter"; @@ -31,6 +32,8 @@ public class ImageFilterBwFilter extends SimpleImageFilter { public FilterRepresentation getDefaultRepresentation() { FilterBasicRepresentation representation = (FilterBasicRepresentation) super.getDefaultRepresentation(); representation.setName("BW Filter"); + representation.setSerializationName(SERIALIZATION_NAME); + representation.setFilterClass(ImageFilterBwFilter.class); representation.setMaximum(180); representation.setMinimum(-180); diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java index 2097f0d6e..c8b41c248 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java @@ -21,6 +21,7 @@ import com.android.gallery3d.R; import android.graphics.Bitmap; public class ImageFilterContrast extends SimpleImageFilter { + private static final String SERIALIZATION_NAME = "CONTRAST"; public ImageFilterContrast() { mName = "Contrast"; @@ -30,6 +31,8 @@ public class ImageFilterContrast extends SimpleImageFilter { FilterBasicRepresentation representation = (FilterBasicRepresentation) super.getDefaultRepresentation(); representation.setName("Contrast"); + representation.setSerializationName(SERIALIZATION_NAME); + representation.setFilterClass(ImageFilterContrast.class); representation.setTextId(R.string.contrast); representation.setButtonId(R.id.contrastButton); diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterDownsample.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterDownsample.java index 0b02fc4f6..ea2ff351d 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterDownsample.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterDownsample.java @@ -24,6 +24,7 @@ import com.android.gallery3d.R; import com.android.gallery3d.filtershow.cache.ImageLoader; public class ImageFilterDownsample extends SimpleImageFilter { + private static final String SERIALIZATION_NAME = "DOWNSAMPLE"; private static final int ICON_DOWNSAMPLE_FRACTION = 8; private ImageLoader mImageLoader; @@ -35,6 +36,8 @@ public class ImageFilterDownsample extends SimpleImageFilter { public FilterRepresentation getDefaultRepresentation() { FilterBasicRepresentation representation = (FilterBasicRepresentation) super.getDefaultRepresentation(); representation.setName("Downsample"); + representation.setSerializationName(SERIALIZATION_NAME); + representation.setFilterClass(ImageFilterDownsample.class); representation.setMaximum(100); representation.setMinimum(1); diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterDraw.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterDraw.java index 1fd9071f7..812ab02f0 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterDraw.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterDraw.java @@ -31,6 +31,7 @@ import android.graphics.PorterDuffColorFilter; import com.android.gallery3d.R; import com.android.gallery3d.filtershow.filters.FilterDrawRepresentation.StrokeData; import com.android.gallery3d.filtershow.imageshow.MasterImage; +import com.android.gallery3d.filtershow.presets.FilterEnvironment; import com.android.gallery3d.filtershow.presets.ImagePreset; import java.util.Vector; @@ -204,7 +205,7 @@ public class ImageFilterDraw extends ImageFilter { public void drawData(Canvas canvas, Matrix originalRotateToScreen, int quality) { Paint paint = new Paint(); - if (quality == ImagePreset.QUALITY_FINAL) { + if (quality == FilterEnvironment.QUALITY_FINAL) { paint.setAntiAlias(true); } paint.setStyle(Style.STROKE); @@ -214,7 +215,7 @@ public class ImageFilterDraw extends ImageFilter { if (mParameters.getDrawing().isEmpty() && mParameters.getCurrentDrawing() == null) { return; } - if (quality == ImagePreset.QUALITY_FINAL) { + if (quality == FilterEnvironment.QUALITY_FINAL) { for (FilterDrawRepresentation.StrokeData strokeData : mParameters.getDrawing()) { paint(strokeData, canvas, originalRotateToScreen, quality); } @@ -248,17 +249,17 @@ public class ImageFilterDraw extends ImageFilter { int n = v.size(); for (int i = mCachedStrokes; i < n; i++) { - paint(v.get(i), drawCache, originalRotateToScreen, ImagePreset.QUALITY_PREVIEW); + paint(v.get(i), drawCache, originalRotateToScreen, FilterEnvironment.QUALITY_PREVIEW); } mCachedStrokes = n; } public void draw(Canvas canvas, Matrix originalRotateToScreen) { for (FilterDrawRepresentation.StrokeData strokeData : mParameters.getDrawing()) { - paint(strokeData, canvas, originalRotateToScreen, ImagePreset.QUALITY_PREVIEW); + paint(strokeData, canvas, originalRotateToScreen, FilterEnvironment.QUALITY_PREVIEW); } mDrawingsTypes[mCurrentStyle].paint( - null, canvas, originalRotateToScreen, ImagePreset.QUALITY_PREVIEW); + null, canvas, originalRotateToScreen, FilterEnvironment.QUALITY_PREVIEW); } @Override diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterEdge.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterEdge.java index 46a9a294c..82de2b73a 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterEdge.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterEdge.java @@ -21,7 +21,7 @@ import android.graphics.Bitmap; import com.android.gallery3d.R; public class ImageFilterEdge extends SimpleImageFilter { - + private static final String SERIALIZATION_NAME = "EDGE"; public ImageFilterEdge() { mName = "Edge"; } @@ -29,6 +29,7 @@ public class ImageFilterEdge extends SimpleImageFilter { public FilterRepresentation getDefaultRepresentation() { FilterRepresentation representation = super.getDefaultRepresentation(); representation.setName("Edge"); + representation.setSerializationName(SERIALIZATION_NAME); representation.setFilterClass(ImageFilterEdge.class); representation.setTextId(R.string.edge); representation.setButtonId(R.id.edgeButton); diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterExposure.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterExposure.java index b0b0b2dd8..6fdcd249b 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterExposure.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterExposure.java @@ -21,7 +21,7 @@ import com.android.gallery3d.R; import android.graphics.Bitmap; public class ImageFilterExposure extends SimpleImageFilter { - + private static final String SERIALIZATION_NAME = "EXPOSURE"; public ImageFilterExposure() { mName = "Exposure"; } @@ -30,6 +30,7 @@ public class ImageFilterExposure extends SimpleImageFilter { FilterBasicRepresentation representation = (FilterBasicRepresentation) super.getDefaultRepresentation(); representation.setName("Exposure"); + representation.setSerializationName(SERIALIZATION_NAME); representation.setFilterClass(ImageFilterExposure.class); representation.setTextId(R.string.exposure); representation.setButtonId(R.id.exposureButton); diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterFx.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterFx.java index 68e8a7c9d..51c66127b 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterFx.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterFx.java @@ -37,6 +37,11 @@ public class ImageFilterFx extends ImageFilter { mFxBitmap = null; } + @Override + public FilterRepresentation getDefaultRepresentation() { + return null; + } + public void useRepresentation(FilterRepresentation representation) { FilterFxRepresentation parameters = (FilterFxRepresentation) representation; mParameters = parameters; @@ -87,4 +92,5 @@ public class ImageFilterFx extends ImageFilter { public void setResources(Resources resources) { mResources = resources; } + } diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterHighlights.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterHighlights.java index 0022a9eae..0725dd1c4 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterHighlights.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterHighlights.java @@ -21,6 +21,7 @@ import android.graphics.Bitmap; import com.android.gallery3d.R; public class ImageFilterHighlights extends SimpleImageFilter { + private static final String SERIALIZATION_NAME = "HIGHLIGHTS"; private static final String LOGTAG = "ImageFilterVignette"; public ImageFilterHighlights() { @@ -33,7 +34,8 @@ public class ImageFilterHighlights extends SimpleImageFilter { public FilterRepresentation getDefaultRepresentation() { FilterBasicRepresentation representation = (FilterBasicRepresentation) super.getDefaultRepresentation(); - representation.setName("Shadows"); + representation.setName("Highlights"); + representation.setSerializationName(SERIALIZATION_NAME); representation.setFilterClass(ImageFilterHighlights.class); representation.setTextId(R.string.highlight_recovery); representation.setButtonId(R.id.highlightRecoveryButton); diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java index b1f9f7365..7e6f68548 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java @@ -22,6 +22,7 @@ import com.android.gallery3d.filtershow.editors.BasicEditor; import android.graphics.Bitmap; public class ImageFilterHue extends SimpleImageFilter { + private static final String SERIALIZATION_NAME = "HUE"; private ColorSpaceMatrix cmatrix = null; public ImageFilterHue() { @@ -33,6 +34,7 @@ public class ImageFilterHue extends SimpleImageFilter { FilterBasicRepresentation representation = (FilterBasicRepresentation) super.getDefaultRepresentation(); representation.setName("Hue"); + representation.setSerializationName(SERIALIZATION_NAME); representation.setFilterClass(ImageFilterHue.class); representation.setMinimum(-180); representation.setMaximum(180); diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterKMeans.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterKMeans.java index 29e6d162f..93813813f 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterKMeans.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterKMeans.java @@ -22,6 +22,7 @@ import android.text.format.Time; import com.android.gallery3d.R; public class ImageFilterKMeans extends SimpleImageFilter { + private static final String SERIALIZATION_NAME = "KMEANS"; private int mSeed = 0; public ImageFilterKMeans() { @@ -36,6 +37,7 @@ public class ImageFilterKMeans extends SimpleImageFilter { public FilterRepresentation getDefaultRepresentation() { FilterBasicRepresentation representation = (FilterBasicRepresentation) super.getDefaultRepresentation(); representation.setName("KMeans"); + representation.setSerializationName(SERIALIZATION_NAME); representation.setFilterClass(ImageFilterKMeans.class); representation.setMaximum(20); representation.setMinimum(2); diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterNegative.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterNegative.java index c256686fb..0747190fa 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterNegative.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterNegative.java @@ -6,13 +6,14 @@ import com.android.gallery3d.R; import com.android.gallery3d.filtershow.editors.ImageOnlyEditor; public class ImageFilterNegative extends ImageFilter { - + private static final String SERIALIZATION_NAME = "NEGATIVE"; public ImageFilterNegative() { mName = "Negative"; } public FilterRepresentation getDefaultRepresentation() { FilterRepresentation representation = new FilterDirectRepresentation("Negative"); + representation.setSerializationName(SERIALIZATION_NAME); representation.setFilterClass(ImageFilterNegative.class); representation.setTextId(R.string.negative); representation.setButtonId(R.id.negativeButton); diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java index cfbb560c7..69d18f805 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java @@ -22,13 +22,14 @@ import android.support.v8.renderscript.*; import android.util.Log; import android.content.res.Resources; import com.android.gallery3d.R; -import com.android.gallery3d.filtershow.cache.CachingPipeline; +import com.android.gallery3d.filtershow.presets.PipelineInterface; public abstract class ImageFilterRS extends ImageFilter { private static final String LOGTAG = "ImageFilterRS"; private boolean DEBUG = false; private int mLastInputWidth = 0; private int mLastInputHeight = 0; + private long mLastTimeCalled; public static boolean PERF_LOGGING = false; @@ -51,26 +52,36 @@ public abstract class ImageFilterRS extends ImageFilter { } protected RenderScript getRenderScriptContext() { - return CachingPipeline.getRenderScriptContext(); + PipelineInterface pipeline = getEnvironment().getPipeline(); + return pipeline.getRSContext(); } protected Allocation getInPixelsAllocation() { - CachingPipeline pipeline = getEnvironment().getCachingPipeline(); + PipelineInterface pipeline = getEnvironment().getPipeline(); return pipeline.getInPixelsAllocation(); } protected Allocation getOutPixelsAllocation() { - CachingPipeline pipeline = getEnvironment().getCachingPipeline(); + PipelineInterface pipeline = getEnvironment().getPipeline(); return pipeline.getOutPixelsAllocation(); } @Override public void apply(Allocation in, Allocation out) { long startOverAll = System.nanoTime(); + if (PERF_LOGGING) { + long delay = (startOverAll - mLastTimeCalled) / 1000; + String msg = String.format("%s; image size %dx%d; ", getName(), + in.getType().getX(), in.getType().getY()); + msg += String.format("called after %.2f ms (%.2f FPS); ", + delay / 1000.f, 1000000.f / delay); + Log.i(LOGTAG, msg); + } + mLastTimeCalled = startOverAll; long startFilter = 0; long endFilter = 0; if (!mResourcesLoaded) { - CachingPipeline pipeline = getEnvironment().getCachingPipeline(); + PipelineInterface pipeline = getEnvironment().getPipeline(); createFilter(pipeline.getResources(), getEnvironment().getScaleFactor(), getEnvironment().getQuality(), in); mResourcesLoaded = true; @@ -102,7 +113,7 @@ public abstract class ImageFilterRS extends ImageFilter { return bitmap; } try { - CachingPipeline pipeline = getEnvironment().getCachingPipeline(); + PipelineInterface pipeline = getEnvironment().getPipeline(); if (DEBUG) { Log.v(LOGTAG, "apply filter " + getName() + " in pipeline " + pipeline.getName()); } @@ -137,18 +148,16 @@ public abstract class ImageFilterRS extends ImageFilter { displayLowMemoryToast(); Log.e(LOGTAG, "not enough memory for filter " + getName(), e); } - return bitmap; } - protected static Allocation convertBitmap(Bitmap bitmap) { - return Allocation.createFromBitmap(CachingPipeline.getRenderScriptContext(), bitmap, + protected static Allocation convertBitmap(RenderScript RS, Bitmap bitmap) { + return Allocation.createFromBitmap(RS, bitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT | Allocation.USAGE_GRAPHICS_TEXTURE); } - private static Allocation convertRGBAtoA(Bitmap bitmap) { - RenderScript RS = CachingPipeline.getRenderScriptContext(); + private static Allocation convertRGBAtoA(RenderScript RS, Bitmap bitmap) { if (RS != mRScache || mGreyConvert == null) { mGreyConvert = new ScriptC_grey(RS, RS.getApplicationContext().getResources(), R.raw.grey); @@ -157,7 +166,7 @@ public abstract class ImageFilterRS extends ImageFilter { Type.Builder tb_a8 = new Type.Builder(RS, Element.A_8(RS)); - Allocation bitmapTemp = convertBitmap(bitmap); + Allocation bitmapTemp = convertBitmap(RS, bitmap); if (bitmapTemp.getType().getElement().isCompatible(Element.A_8(RS))) { return bitmapTemp; } @@ -173,20 +182,20 @@ public abstract class ImageFilterRS extends ImageFilter { } public Allocation loadScaledResourceAlpha(int resource, int inSampleSize) { - Resources res = CachingPipeline.getResources(); + Resources res = getEnvironment().getPipeline().getResources(); final BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.ALPHA_8; options.inSampleSize = inSampleSize; Bitmap bitmap = BitmapFactory.decodeResource( res, resource, options); - Allocation ret = convertRGBAtoA(bitmap); + Allocation ret = convertRGBAtoA(getRenderScriptContext(), bitmap); bitmap.recycle(); return ret; } public Allocation loadScaledResourceAlpha(int resource, int w, int h, int inSampleSize) { - Resources res = CachingPipeline.getResources(); + Resources res = getEnvironment().getPipeline().getResources(); final BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.ALPHA_8; options.inSampleSize = inSampleSize; @@ -194,7 +203,7 @@ public abstract class ImageFilterRS extends ImageFilter { res, resource, options); Bitmap resizeBitmap = Bitmap.createScaledBitmap(bitmap, w, h, true); - Allocation ret = convertRGBAtoA(resizeBitmap); + Allocation ret = convertRGBAtoA(getRenderScriptContext(), resizeBitmap); resizeBitmap.recycle(); bitmap.recycle(); return ret; @@ -205,13 +214,13 @@ public abstract class ImageFilterRS extends ImageFilter { } public Allocation loadResource(int resource) { - Resources res = CachingPipeline.getResources(); + Resources res = getEnvironment().getPipeline().getResources(); final BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.ARGB_8888; Bitmap bitmap = BitmapFactory.decodeResource( res, resource, options); - Allocation ret = convertBitmap(bitmap); + Allocation ret = convertBitmap(getRenderScriptContext(), bitmap); bitmap.recycle(); return ret; } @@ -232,7 +241,7 @@ public abstract class ImageFilterRS extends ImageFilter { /** * RS Script objects (and all other RS objects) should be cleared here */ - abstract protected void resetScripts(); + public abstract void resetScripts(); /** * Scripts values should be bound here @@ -244,6 +253,8 @@ public abstract class ImageFilterRS extends ImageFilter { return; } resetAllocations(); + mLastInputWidth = 0; + mLastInputHeight = 0; setResourcesLoaded(false); } } diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java index 0febe4957..adc74c5ec 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java @@ -21,7 +21,7 @@ import com.android.gallery3d.R; import android.graphics.Bitmap; public class ImageFilterSaturated extends SimpleImageFilter { - + private static final String SERIALIZATION_NAME = "SATURATED"; public ImageFilterSaturated() { mName = "Saturated"; } @@ -31,6 +31,7 @@ public class ImageFilterSaturated extends SimpleImageFilter { FilterBasicRepresentation representation = (FilterBasicRepresentation) super.getDefaultRepresentation(); representation.setName("Saturated"); + representation.setSerializationName(SERIALIZATION_NAME); representation.setFilterClass(ImageFilterSaturated.class); representation.setTextId(R.string.saturation); representation.setButtonId(R.id.saturationButton); diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java index fd67ee8fc..845290b80 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java @@ -21,7 +21,7 @@ import com.android.gallery3d.R; import android.graphics.Bitmap; public class ImageFilterShadows extends SimpleImageFilter { - + private static final String SERIALIZATION_NAME = "SHADOWS"; public ImageFilterShadows() { mName = "Shadows"; @@ -31,6 +31,7 @@ public class ImageFilterShadows extends SimpleImageFilter { FilterBasicRepresentation representation = (FilterBasicRepresentation) super.getDefaultRepresentation(); representation.setName("Shadows"); + representation.setSerializationName(SERIALIZATION_NAME); representation.setFilterClass(ImageFilterShadows.class); representation.setTextId(R.string.shadow_recovery); representation.setButtonId(R.id.shadowRecoveryButton); diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterSharpen.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterSharpen.java index 76ae475ac..1dc2c0516 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterSharpen.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterSharpen.java @@ -19,7 +19,7 @@ package com.android.gallery3d.filtershow.filters; import com.android.gallery3d.R; public class ImageFilterSharpen extends ImageFilterRS { - + private static final String SERIALIZATION_NAME = "SHARPEN"; private static final String LOGTAG = "ImageFilterSharpen"; private ScriptC_convolve3x3 mScript; @@ -31,6 +31,7 @@ public class ImageFilterSharpen extends ImageFilterRS { public FilterRepresentation getDefaultRepresentation() { FilterRepresentation representation = new FilterBasicRepresentation("Sharpen", 0, 0, 100); + representation.setSerializationName(SERIALIZATION_NAME); representation.setShowParameterValue(true); representation.setFilterClass(ImageFilterSharpen.class); representation.setTextId(R.string.sharpness); @@ -52,7 +53,7 @@ public class ImageFilterSharpen extends ImageFilterRS { } @Override - protected void resetScripts() { + public void resetScripts() { if (mScript != null) { mScript.destroy(); mScript = null; diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterTinyPlanet.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterTinyPlanet.java index 37d5739a0..f265c4dcc 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterTinyPlanet.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterTinyPlanet.java @@ -76,7 +76,7 @@ public class ImageFilterTinyPlanet extends SimpleImageFilter { int w = bitmapIn.getWidth(); int h = bitmapIn.getHeight(); int outputSize = (int) (w / 2f); - ImagePreset preset = getImagePreset(); + ImagePreset preset = getEnvironment().getImagePreset(); Bitmap mBitmapOut = null; if (preset != null) { XMPMeta xmp = preset.getImageLoader().getXmpObject(); diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterVibrance.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterVibrance.java index ea315d326..900fd906c 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterVibrance.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterVibrance.java @@ -21,7 +21,7 @@ import com.android.gallery3d.R; import android.graphics.Bitmap; public class ImageFilterVibrance extends SimpleImageFilter { - + private static final String SERIALIZATION_NAME = "VIBRANCE"; public ImageFilterVibrance() { mName = "Vibrance"; } @@ -30,6 +30,7 @@ public class ImageFilterVibrance extends SimpleImageFilter { FilterBasicRepresentation representation = (FilterBasicRepresentation) super.getDefaultRepresentation(); representation.setName("Vibrance"); + representation.setSerializationName(SERIALIZATION_NAME); representation.setFilterClass(ImageFilterVibrance.class); representation.setTextId(R.string.vibrance); representation.setButtonId(R.id.vibranceButton); diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java index e06f54493..cfe135033 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java @@ -22,7 +22,7 @@ import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Rect; import com.android.gallery3d.R; -import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.presets.FilterEnvironment; public class ImageFilterVignette extends SimpleImageFilter { private static final String LOGTAG = "ImageFilterVignette"; @@ -57,9 +57,9 @@ public class ImageFilterVignette extends SimpleImageFilter { @Override public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) { - if (SIMPLE_ICONS && ImagePreset.QUALITY_ICON == quality) { + if (SIMPLE_ICONS && FilterEnvironment.QUALITY_ICON == quality) { if (mOverlayBitmap == null) { - Resources res = getEnvironment().getCachingPipeline().getResources(); + Resources res = getEnvironment().getPipeline().getResources(); mOverlayBitmap = IconUtilities.getFXBitmap(res, R.drawable.filtershow_icon_vignette); } diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterWBalance.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterWBalance.java index c4c293a4b..84a14c902 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterWBalance.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterWBalance.java @@ -22,6 +22,7 @@ import com.android.gallery3d.filtershow.editors.ImageOnlyEditor; import android.graphics.Bitmap; public class ImageFilterWBalance extends ImageFilter { + private static final String SERIALIZATION_NAME = "WBALANCE"; private static final String TAG = "ImageFilterWBalance"; public ImageFilterWBalance() { @@ -30,6 +31,7 @@ public class ImageFilterWBalance extends ImageFilter { public FilterRepresentation getDefaultRepresentation() { FilterRepresentation representation = new FilterDirectRepresentation("WBalance"); + representation.setSerializationName(SERIALIZATION_NAME); representation.setFilterClass(ImageFilterWBalance.class); representation.setPriority(FilterRepresentation.TYPE_WBALANCE); representation.setTextId(R.string.wbalance); diff --git a/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java b/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java index e5820a8f2..77dbd5e7b 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java +++ b/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java @@ -20,6 +20,7 @@ import android.graphics.Bitmap; import android.graphics.Matrix; import android.graphics.Rect; import android.graphics.RectF; +import android.util.Log; import com.android.gallery3d.filtershow.cache.ImageLoader; import com.android.gallery3d.filtershow.crop.CropExtras; @@ -30,7 +31,14 @@ import com.android.gallery3d.filtershow.editors.EditorStraighten; import com.android.gallery3d.filtershow.filters.FilterRepresentation; import com.android.gallery3d.filtershow.filters.ImageFilterGeometry; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; + public class GeometryMetadata extends FilterRepresentation { + private static final String SERIALIZATION_NAME = "GEOM"; private static final String LOGTAG = "GeometryMetadata"; private float mScaleFactor = 1.0f; private float mRotation = 0; @@ -40,7 +48,26 @@ public class GeometryMetadata extends FilterRepresentation { private FLIP mFlip = FLIP.NONE; public enum FLIP { - NONE, VERTICAL, HORIZONTAL, BOTH + NONE("N"), VERTICAL("V"), HORIZONTAL("H"), BOTH("B"); + String mValue; + + FLIP(String name) { + mValue = name; + } + + public static FLIP parse(String name){ + switch (name.charAt(0)) { + case 'N': + return NONE; + case 'V': + return VERTICAL; + case 'H': + return HORIZONTAL; + case 'B': + return BOTH; + }; + return NONE; + } } // Output format data from intent extras @@ -64,6 +91,7 @@ public class GeometryMetadata extends FilterRepresentation { public GeometryMetadata() { super("GeometryMetadata"); + setSerializationName(SERIALIZATION_NAME); setFilterClass(ImageFilterGeometry.class); setEditorId(EditorCrop.ID); setTextId(0); @@ -492,4 +520,87 @@ public class GeometryMetadata extends FilterRepresentation { representation.useParametersFrom(this); return representation; } + + private static final String[] sParams = { + "Name", "ScaleFactor", "Rotation", "StraightenRotation", "CropBoundsLeft", + "CropBoundsTop", "CropBoundsRight", "CropBoundsBottom", "PhotoBoundsLeft", + "PhotoBoundsTop", "PhotoBoundsRight", "PhotoBoundsBottom", "Flip" + }; + + @Override + public String[][] serializeRepresentation() { + String[][] ret = { + { "Name", getName() }, + { "ScaleFactor", Float.toString(mScaleFactor) }, + { "Rotation", Float.toString(mRotation) }, + { "StraightenRotation", Float.toString(mStraightenRotation) }, + { "CropBoundsLeft", Float.toString(mCropBounds.left) }, + { "CropBoundsTop", Float.toString(mCropBounds.top) }, + { "CropBoundsRight", Float.toString(mCropBounds.right) }, + { "CropBoundsBottom", Float.toString(mCropBounds.bottom) }, + { "PhotoBoundsLeft", Float.toString(mPhotoBounds.left) }, + { "PhotoBoundsTop", Float.toString(mPhotoBounds.top) }, + { "PhotoBoundsRight", Float.toString(mPhotoBounds.right) }, + { "PhotoBoundsBottom", Float.toString(mPhotoBounds.bottom) }, + { "Flip", mFlip.mValue } }; + return ret; + } + + @Override + public void deSerializeRepresentation(String[][] rep) { + HashMap<String, Integer> map = new HashMap<String, Integer>(); + for (int i = 0; i < sParams.length; i++) { + map.put(sParams[i], i); + } + for (int i = 0; i < rep.length; i++) { + String key = rep[i][0]; + String value = rep[i][1]; + + switch (map.get(key)) { + case -1: // Unknown + break; + case 0: + if (!getName().equals(value)) { + throw new IllegalArgumentException("Not a "+getName()); + } + break; + case 1: // "ScaleFactor", Float + mScaleFactor = Float.parseFloat(value); + break; + case 2: // "Rotation", Float + mRotation = Float.parseFloat(value); + break; + case 3: // "StraightenRotation", Float + mStraightenRotation = Float.parseFloat(value); + break; + case 4: // "mCropBoundsLeft", Float + mCropBounds.left = Float.parseFloat(value); + break; + case 5: // "mCropBoundsTop", Float + mCropBounds.top = Float.parseFloat(value); + break; + case 6: // "mCropBoundsRight", Float + mCropBounds.right = Float.parseFloat(value); + break; + case 7: // "mCropBoundsBottom", Float + mCropBounds.bottom = Float.parseFloat(value); + break; + case 8: // "mPhotoBoundsLeft", Float + mPhotoBounds.left = Float.parseFloat(value); + break; + case 9: // "mPhotoBoundsTop", Float + mPhotoBounds.top = Float.parseFloat(value); + break; + case 10: // "mPhotoBoundsRight", Float + mPhotoBounds.right = Float.parseFloat(value); + break; + case 11: // "mPhotoBoundsBottom", Float + mPhotoBounds.bottom = Float.parseFloat(value); + break; + case 12: // "Flip", enum + mFlip = FLIP.parse(value); + break; + } + } + } } diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageDraw.java b/src/com/android/gallery3d/filtershow/imageshow/ImageDraw.java index 8fcc028af..67a093bfb 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageDraw.java +++ b/src/com/android/gallery3d/filtershow/imageshow/ImageDraw.java @@ -26,13 +26,11 @@ 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) { @@ -97,8 +95,6 @@ public class ImageDraw extends ImageShow { } } - ImageFilterDraw filter = (ImageFilterDraw) getCurrentFilter(); - if (event.getAction() == MotionEvent.ACTION_DOWN) { calcScreenMapping(); mTmpPoint[0] = event.getX(); @@ -110,7 +106,6 @@ public class ImageDraw extends ImageShow { if (event.getAction() == MotionEvent.ACTION_MOVE) { int historySize = event.getHistorySize(); - final int pointerCount = event.getPointerCount(); for (int h = 0; h < historySize; h++) { int p = 0; { diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java b/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java index 0c51b165e..b077c10ff 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java +++ b/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java @@ -314,11 +314,6 @@ public abstract class ImageGeometry extends ImageShow { mMode = MODES.NONE; } - @Override - public boolean showTitle() { - return false; - } - public String getName() { return "Geometry"; } @@ -409,10 +404,6 @@ public abstract class ImageGeometry extends ImageShow { @Override public void onDraw(Canvas canvas) { - if (getDirtyGeometryFlag()) { - syncLocalToMasterGeometry(); - clearDirtyGeometryFlag(); - } Bitmap image = getFiltersOnlyImage(); if (image == null) { invalidate(); @@ -480,7 +471,7 @@ public abstract class ImageGeometry extends ImageShow { p.setStrokeWidth(2); canvas.drawPath(path, p); - p.setColor(getDefaultBackgroundColor()); + p.setColor(mBackgroundColor); p.setAlpha(128); p.setStyle(Paint.Style.FILL); drawShadows(canvas, p, scaledCrop); @@ -518,7 +509,7 @@ public abstract class ImageGeometry extends ImageShow { canvas.drawBitmap(photo, m1, p); canvas.restore(); - p.setColor(getDefaultBackgroundColor()); + p.setColor(mBackgroundColor); p.setStyle(Paint.Style.FILL); scaledCrop.offset(displayCenter[0] - scaledCrop.centerX(), displayCenter[1] - scaledCrop.centerY()); diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java b/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java index b833cf858..1b9398397 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java +++ b/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java @@ -17,6 +17,7 @@ package com.android.gallery3d.filtershow.imageshow; import android.content.Context; +import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; @@ -25,8 +26,6 @@ import android.graphics.Paint; import android.graphics.Point; import android.graphics.Rect; import android.graphics.RectF; -import android.net.Uri; -import android.os.Handler; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.GestureDetector.OnDoubleTapListener; @@ -36,6 +35,7 @@ import android.view.ScaleGestureDetector; import android.view.View; import android.widget.LinearLayout; +import com.android.gallery3d.R; import com.android.gallery3d.filtershow.FilterShowActivity; import com.android.gallery3d.filtershow.cache.ImageLoader; import com.android.gallery3d.filtershow.filters.ImageFilter; @@ -51,15 +51,12 @@ public class ImageShow extends View implements OnGestureListener, private static final boolean ENABLE_ZOOMED_COMPARISON = false; protected Paint mPaint = new Paint(); - protected static int mTextSize = 24; - protected static int mTextPadding = 20; + protected int mTextSize; + protected int mTextPadding; protected ImageLoader mImageLoader = null; - private boolean mDirtyGeometry = false; - private Bitmap mBackgroundImage = null; - private final boolean USE_BACKGROUND_IMAGE = false; - private static int mBackgroundColor = Color.RED; + protected int mBackgroundColor; private GestureDetector mGestureDetector = null; private ScaleGestureDetector mScaleGestureDetector = null; @@ -69,7 +66,6 @@ public class ImageShow extends View implements OnGestureListener, private boolean mTouchShowOriginal = false; private long mTouchShowOriginalDate = 0; private final long mTouchShowOriginalDelayMin = 200; // 200ms - private final long mTouchShowOriginalDelayMax = 300; // 300ms private int mShowOriginalDirection = 0; private static int UNVEIL_HORIZONTAL = 1; private static int UNVEIL_VERTICAL = 2; @@ -78,9 +74,9 @@ public class ImageShow extends View implements OnGestureListener, private Point mTouch = new Point(); private boolean mFinishedScalingOperation = false; - private static int mOriginalTextMargin = 8; - private static int mOriginalTextSize = 26; - private static String mOriginalText = "Original"; + private int mOriginalTextMargin; + private int mOriginalTextSize; + private String mOriginalText; private boolean mZoomIn = false; Point mOriginalTranslation = new Point(); float mOriginalScale; @@ -90,9 +86,6 @@ public class ImageShow extends View implements OnGestureListener, SCALE, MOVE } - private String mToast = null; - private boolean mShowToast = false; - private boolean mImportantToast = false; InteractionMode mInteractionMode = InteractionMode.NONE; protected GeometryMetadata getGeometry() { @@ -101,46 +94,10 @@ public class ImageShow extends View implements OnGestureListener, private FilterShowActivity mActivity = null; - public static void setDefaultBackgroundColor(int value) { - mBackgroundColor = value; - } - public FilterShowActivity getActivity() { return mActivity; } - public int getDefaultBackgroundColor() { - return mBackgroundColor; - } - - public static void setTextSize(int value) { - mTextSize = value; - } - - public static void setTextPadding(int value) { - mTextPadding = value; - } - - public static void setOriginalTextMargin(int value) { - mOriginalTextMargin = value; - } - - public static void setOriginalTextSize(int value) { - mOriginalTextSize = value; - } - - public static void setOriginalText(String text) { - mOriginalText = text; - } - - private final Handler mHandler = new Handler(); - - public void select() { - } - - public void unselect() { - } - public boolean hasModifications() { if (getImagePreset() == null) { return false; @@ -157,21 +114,30 @@ public class ImageShow extends View implements OnGestureListener, mActivity.enableSave(hasModifications()); } - public Point getTouchPoint() { - return mTouch; + public ImageShow(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + setupImageShow(context); } public ImageShow(Context context, AttributeSet attrs) { super(context, attrs); + setupImageShow(context); - setupGestureDetector(context); - mActivity = (FilterShowActivity) context; - MasterImage.getImage().addObserver(this); } public ImageShow(Context context) { super(context); + setupImageShow(context); + } + private void setupImageShow(Context context) { + Resources res = context.getResources(); + mTextSize = res.getDimensionPixelSize(R.dimen.photoeditor_text_size); + mTextPadding = res.getDimensionPixelSize(R.dimen.photoeditor_text_padding); + mOriginalTextMargin = res.getDimensionPixelSize(R.dimen.photoeditor_original_text_margin); + mOriginalTextSize = res.getDimensionPixelSize(R.dimen.photoeditor_original_text_size); + mBackgroundColor = res.getColor(R.color.background_screen); + mOriginalText = res.getString(R.string.original_picture_text); setupGestureDetector(context); mActivity = (FilterShowActivity) context; MasterImage.getImage().addObserver(this); @@ -193,25 +159,6 @@ public class ImageShow extends View implements OnGestureListener, return MasterImage.getImage().getCurrentFilter(); } - public void showToast(String text) { - showToast(text, false); - } - - public void showToast(String text, boolean important) { - mToast = text; - mShowToast = true; - mImportantToast = important; - invalidate(); - - mHandler.postDelayed(new Runnable() { - @Override - public void run() { - mShowToast = false; - invalidate(); - } - }, 400); - } - public Rect getImageBounds() { Rect dst = new Rect(); getImagePreset().mGeoData.getPhotoBounds().roundOut(dst); @@ -258,38 +205,10 @@ public class ImageShow extends View implements OnGestureListener, return invert; } - public Rect getDisplayedImageBounds() { - return mImageBounds; - } - public ImagePreset getImagePreset() { return MasterImage.getImage().getPreset(); } - public void drawToast(Canvas canvas) { - if (mShowToast && mToast != null) { - Paint paint = new Paint(); - paint.setTextSize(128); - float textWidth = paint.measureText(mToast); - int toastX = (int) ((getWidth() - textWidth) / 2.0f); - int toastY = (int) (getHeight() / 3.0f); - - paint.setARGB(255, 0, 0, 0); - canvas.drawText(mToast, toastX - 2, toastY - 2, paint); - canvas.drawText(mToast, toastX - 2, toastY, paint); - canvas.drawText(mToast, toastX, toastY - 2, paint); - canvas.drawText(mToast, toastX + 2, toastY + 2, paint); - canvas.drawText(mToast, toastX + 2, toastY, paint); - canvas.drawText(mToast, toastX, toastY + 2, paint); - if (mImportantToast) { - paint.setARGB(255, 200, 0, 0); - } else { - paint.setARGB(255, 255, 255, 255); - } - canvas.drawText(mToast, toastX, toastY, paint); - } - } - @Override public void onDraw(Canvas canvas) { MasterImage.getImage().setImageShowSize(getWidth(), getHeight()); @@ -320,7 +239,6 @@ public class ImageShow extends View implements OnGestureListener, // TODO: center scale on gesture canvas.scale(scaleFactor, scaleFactor, cx, cy); canvas.translate(translation.x, translation.y); - drawBackground(canvas); drawImage(canvas, getFilteredImage(), true); Bitmap highresPreview = MasterImage.getImage().getHighresImage(); if (highresPreview != null) { @@ -328,17 +246,6 @@ public class ImageShow extends View implements OnGestureListener, } canvas.restore(); - if (showTitle() && getImagePreset() != null) { - mPaint.setARGB(200, 0, 0, 0); - mPaint.setTextSize(mTextSize); - - Rect textRect = new Rect(0, 0, getWidth(), mTextSize + mTextPadding); - canvas.drawRect(textRect, mPaint); - mPaint.setARGB(255, 200, 200, 200); - canvas.drawText(getImagePreset().name(), mTextPadding, - 1.5f * mTextPadding, mPaint); - } - Bitmap partialPreview = MasterImage.getImage().getPartialImage(); if (partialPreview != null) { Rect src = new Rect(0, 0, partialPreview.getWidth(), partialPreview.getHeight()); @@ -353,8 +260,6 @@ public class ImageShow extends View implements OnGestureListener, canvas.restore(); canvas.restore(); - - drawToast(canvas); } public void resetImageCaches(ImageShow caller) { @@ -459,26 +364,6 @@ public class ImageShow extends View implements OnGestureListener, canvas.restore(); } - public void drawBackground(Canvas canvas) { - if (USE_BACKGROUND_IMAGE) { - if (mBackgroundImage == null) { - mBackgroundImage = mImageLoader.getBackgroundBitmap(getResources()); - } - if (mBackgroundImage != null) { - Rect s = new Rect(0, 0, mBackgroundImage.getWidth(), - mBackgroundImage.getHeight()); - Rect d = new Rect(0, 0, getWidth(), getHeight()); - canvas.drawBitmap(mBackgroundImage, s, d, mPaint); - } - } else { - canvas.drawARGB(0, 0, 0, 0); - } - } - - public boolean showTitle() { - return false; - } - public void setImageLoader(ImageLoader loader) { mImageLoader = loader; if (mImageLoader != null) { @@ -487,18 +372,6 @@ public class ImageShow extends View implements OnGestureListener, } } - private void setDirtyGeometryFlag() { - mDirtyGeometry = true; - } - - protected void clearDirtyGeometryFlag() { - mDirtyGeometry = false; - } - - protected boolean getDirtyGeometryFlag() { - return mDirtyGeometry; - } - private void imageSizeChanged(Bitmap image) { if (image == null || getImagePreset() == null) return; @@ -515,15 +388,8 @@ public class ImageShow extends View implements OnGestureListener, } - public boolean updateGeometryFlags() { - return true; - } - public void updateImage() { invalidate(); - if (!updateGeometryFlags()) { - return; - } Bitmap bitmap = mImageLoader.getOriginalBitmapLarge(); if (bitmap != null) { imageSizeChanged(bitmap); @@ -539,26 +405,11 @@ public class ImageShow extends View implements OnGestureListener, mImageLoader.saveImage(getImagePreset(), filterShowActivity, file); } - public void saveToUri(Bitmap f, Uri u, String m, FilterShowActivity filterShowActivity) { - mImageLoader.saveToUri(f, u, m, filterShowActivity); - } - - public void returnFilteredResult(FilterShowActivity filterShowActivity) { - 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); @@ -600,6 +451,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); + constrainTranslation(translation, scaleFactor); MasterImage.getImage().setTranslation(translation); mTouchShowOriginal = false; } else if (enableComparison() && !mOriginalDisabled @@ -630,11 +482,6 @@ public class ImageShow extends View implements OnGestureListener, return true; } - // listview stuff - public void showOriginal(boolean show) { - invalidate(); - } - @Override public boolean onDoubleTap(MotionEvent arg0) { mZoomIn = !mZoomIn; @@ -644,26 +491,44 @@ public class ImageShow extends View implements OnGestureListener, } if (scale != MasterImage.getImage().getScaleFactor()) { MasterImage.getImage().setScaleFactor(scale); + float translateX = (getWidth() / 2 - arg0.getX()); + float translateY = (getHeight() / 2 - arg0.getY()); + Point translation = MasterImage.getImage().getTranslation(); + translation.x = (int) (mOriginalTranslation.x + translateX); + translation.y = (int) (mOriginalTranslation.y + translateY); + constrainTranslation(translation, scale); + MasterImage.getImage().setTranslation(translation); invalidate(); } return true; } + private void constrainTranslation(Point translation, float scale) { + float maxTranslationX = getWidth() / scale; + float maxTranslationY = getHeight() / scale; + if (Math.abs(translation.x) > maxTranslationX) { + translation.x = (int) (Math.signum(translation.x) * + maxTranslationX); + if (Math.abs(translation.y) > maxTranslationY) { + translation.y = (int) (Math.signum(translation.y) * + maxTranslationY); + } + + } + } + @Override public boolean onDoubleTapEvent(MotionEvent arg0) { - // TODO Auto-generated method stub return false; } @Override public boolean onSingleTapConfirmed(MotionEvent arg0) { - // TODO Auto-generated method stub return false; } @Override public boolean onDown(MotionEvent arg0) { - // TODO Auto-generated method stub return false; } @@ -680,23 +545,19 @@ public class ImageShow extends View implements OnGestureListener, @Override public void onLongPress(MotionEvent arg0) { - // TODO Auto-generated method stub } @Override public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2, float arg3) { - // TODO Auto-generated method stub return false; } @Override public void onShowPress(MotionEvent arg0) { - // TODO Auto-generated method stub } @Override public boolean onSingleTapUp(MotionEvent arg0) { - // TODO Auto-generated method stub return false; } @@ -705,14 +566,12 @@ public class ImageShow extends View implements OnGestureListener, } public void openUtilityPanel(final LinearLayout accessoryViewList) { - // TODO Auto-generated method stub } @Override public boolean onScale(ScaleGestureDetector detector) { MasterImage img = MasterImage.getImage(); float scaleFactor = img.getScaleFactor(); - Point pos = img.getTranslation(); scaleFactor = scaleFactor * detector.getScaleFactor(); if (scaleFactor > MasterImage.getImage().getMaxScaleFactor()) { @@ -723,7 +582,6 @@ public class ImageShow extends View implements OnGestureListener, } MasterImage.getImage().setScaleFactor(scaleFactor); scaleFactor = img.getScaleFactor(); - pos = img.getTranslation(); float focusx = detector.getFocusX(); float focusy = detector.getFocusY(); float translateX = (focusx - mStartFocusX) / scaleFactor; @@ -731,6 +589,7 @@ public class ImageShow extends View implements OnGestureListener, Point translation = MasterImage.getImage().getTranslation(); translation.x = (int) (mOriginalTranslation.x + translateX); translation.y = (int) (mOriginalTranslation.y + translateY); + constrainTranslation(translation, scaleFactor); MasterImage.getImage().setTranslation(translation); invalidate(); diff --git a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java index a0b59c0f8..8f490ca5e 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java +++ b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java @@ -20,6 +20,7 @@ import android.graphics.*; import android.os.Handler; import android.os.Message; +import android.util.Log; import com.android.gallery3d.filtershow.FilterShowActivity; import com.android.gallery3d.filtershow.HistoryAdapter; import com.android.gallery3d.filtershow.cache.*; @@ -34,7 +35,7 @@ public class MasterImage implements RenderingRequestCaller { private static final String LOGTAG = "MasterImage"; private boolean DEBUG = false; - private static final boolean DISABLEZOOM = true; + private static final boolean DISABLEZOOM = false; private static MasterImage sMasterImage = null; private static int sIconSeedSize = 128; private static float sHistoryPreviewSize = 128.0f; @@ -139,6 +140,7 @@ public class MasterImage implements RenderingRequestCaller { } public synchronized void setPreset(ImagePreset preset, boolean addToHistory) { + preset.showFilters(); mPreset = preset; mPreset.setImageLoader(mLoader); setGeometry(); diff --git a/src/com/android/gallery3d/filtershow/presets/FilterEnvironment.java b/src/com/android/gallery3d/filtershow/presets/FilterEnvironment.java index c454c1ab6..8d59c9f54 100644 --- a/src/com/android/gallery3d/filtershow/presets/FilterEnvironment.java +++ b/src/com/android/gallery3d/filtershow/presets/FilterEnvironment.java @@ -18,11 +18,9 @@ package com.android.gallery3d.filtershow.presets; import android.graphics.Bitmap; import android.support.v8.renderscript.Allocation; -import android.util.Log; -import com.android.gallery3d.filtershow.cache.CachingPipeline; import com.android.gallery3d.filtershow.filters.FilterRepresentation; -import com.android.gallery3d.filtershow.filters.FiltersManager; +import com.android.gallery3d.filtershow.filters.FiltersManagerInterface; import com.android.gallery3d.filtershow.filters.ImageFilter; import java.lang.ref.WeakReference; @@ -33,10 +31,14 @@ public class FilterEnvironment { private ImagePreset mImagePreset; private float mScaleFactor; private int mQuality; - private FiltersManager mFiltersManager; - private CachingPipeline mCachingPipeline; + private FiltersManagerInterface mFiltersManager; + private PipelineInterface mPipeline; private volatile boolean mStop = false; + public static final int QUALITY_ICON = 0; + public static final int QUALITY_PREVIEW = 1; + public static final int QUALITY_FINAL = 2; + public synchronized boolean needsStop() { return mStop; } @@ -48,6 +50,9 @@ public class FilterEnvironment { private HashMap<Long, WeakReference<Bitmap>> bitmapCach = new HashMap<Long, WeakReference<Bitmap>>(); + private HashMap<Integer, Integer> + generalParameters = new HashMap<Integer, Integer>(); + public void cache(Bitmap bitmap) { if (bitmap == null) { return; @@ -98,11 +103,11 @@ public class FilterEnvironment { return mQuality; } - public void setFiltersManager(FiltersManager filtersManager) { + public void setFiltersManager(FiltersManagerInterface filtersManager) { mFiltersManager = filtersManager; } - public FiltersManager getFiltersManager() { + public FiltersManagerInterface getFiltersManager() { return mFiltersManager; } @@ -114,6 +119,7 @@ public class FilterEnvironment { if (filter.supportsAllocationInput()) { filter.apply(in, out); } + filter.setGeneralParameters(); filter.setEnvironment(null); } @@ -122,16 +128,36 @@ public class FilterEnvironment { filter.useRepresentation(representation); filter.setEnvironment(this); Bitmap ret = filter.apply(bitmap, mScaleFactor, mQuality); + filter.setGeneralParameters(); filter.setEnvironment(null); return ret; } - public CachingPipeline getCachingPipeline() { - return mCachingPipeline; + public PipelineInterface getPipeline() { + return mPipeline; + } + + public void setPipeline(PipelineInterface cachingPipeline) { + mPipeline = cachingPipeline; + } + + public synchronized void clearGeneralParameters() { + generalParameters = null; } - public void setCachingPipeline(CachingPipeline cachingPipeline) { - mCachingPipeline = cachingPipeline; + public synchronized Integer getGeneralParameter(int id) { + if (generalParameters == null || !generalParameters.containsKey(id)) { + return null; + } + return generalParameters.get(id); + } + + public synchronized void setGeneralParameter(int id, int value) { + if (generalParameters == null) { + generalParameters = new HashMap<Integer, Integer>(); + } + + generalParameters.put(id, value); } } diff --git a/src/com/android/gallery3d/filtershow/presets/ImagePreset.java b/src/com/android/gallery3d/filtershow/presets/ImagePreset.java index 2a7e601ee..84766958d 100644 --- a/src/com/android/gallery3d/filtershow/presets/ImagePreset.java +++ b/src/com/android/gallery3d/filtershow/presets/ImagePreset.java @@ -18,12 +18,19 @@ package com.android.gallery3d.filtershow.presets; import android.graphics.Bitmap; import android.graphics.Rect; +import android.net.Uri; import android.support.v8.renderscript.Allocation; +import android.util.JsonReader; +import android.util.JsonWriter; import android.util.Log; +import com.adobe.xmp.XMPException; +import com.adobe.xmp.XMPMeta; +import com.adobe.xmp.options.PropertyOptions; import com.android.gallery3d.filtershow.cache.CachingPipeline; import com.android.gallery3d.filtershow.cache.ImageLoader; import com.android.gallery3d.filtershow.filters.BaseFiltersManager; +import com.android.gallery3d.filtershow.filters.FiltersManager; import com.android.gallery3d.filtershow.filters.FilterRepresentation; import com.android.gallery3d.filtershow.filters.ImageFilter; import com.android.gallery3d.filtershow.imageshow.GeometryMetadata; @@ -32,6 +39,10 @@ import com.android.gallery3d.filtershow.state.State; import com.android.gallery3d.filtershow.state.StateAdapter; import com.android.gallery3d.util.UsageStatistics; +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.ArrayList; import java.util.Vector; public class ImagePreset { @@ -39,10 +50,8 @@ public class ImagePreset { private static final String LOGTAG = "ImagePreset"; private FilterRepresentation mBorder = null; - public static final int QUALITY_ICON = 0; - public static final int QUALITY_PREVIEW = 1; - public static final int QUALITY_FINAL = 2; public static final int STYLE_ICON = 3; + public static final String PRESET_NAME = "PresetName"; private ImageLoader mImageLoader = null; @@ -210,11 +219,11 @@ public class ImagePreset { } for (FilterRepresentation representation : mFilters) { if (representation.getPriority() == FilterRepresentation.TYPE_VIGNETTE - && !representation.isNil()) { + && !representation.isNil()) { return false; } if (representation.getPriority() == FilterRepresentation.TYPE_TINYPLANET - && !representation.isNil()) { + && !representation.isNil()) { return false; } } @@ -460,7 +469,7 @@ public class ImagePreset { if (mBorder != null && mDoApplyGeometry) { mBorder.synchronizeRepresentation(); bitmap = environment.applyRepresentation(mBorder, bitmap); - if (environment.getQuality() == QUALITY_FINAL) { + if (environment.getQuality() == FilterEnvironment.QUALITY_FINAL) { UsageStatistics.onEvent(UsageStatistics.COMPONENT_EDITOR, "SaveBorder", mBorder.getName(), 1); } @@ -468,6 +477,10 @@ public class ImagePreset { return bitmap; } + public int nbFilters() { + return mFilters.size(); + } + public Bitmap applyFilters(Bitmap bitmap, int from, int to, FilterEnvironment environment) { if (mDoApplyFilters) { if (from < 0) { @@ -483,7 +496,7 @@ public class ImagePreset { representation.synchronizeRepresentation(); } bitmap = environment.applyRepresentation(representation, bitmap); - if (environment.getQuality() == QUALITY_FINAL) { + if (environment.getQuality() == FilterEnvironment.QUALITY_FINAL) { UsageStatistics.onEvent(UsageStatistics.COMPONENT_EDITOR, "SaveFilter", representation.getName(), 1); } @@ -496,17 +509,23 @@ public class ImagePreset { return bitmap; } - public void applyBorder(Allocation in, Allocation out, FilterEnvironment environment) { + public void applyBorder(Allocation in, Allocation out, + boolean copyOut, FilterEnvironment environment) { if (mBorder != null && mDoApplyGeometry) { mBorder.synchronizeRepresentation(); // TODO: should keep the bitmap around - Allocation bitmapIn = Allocation.createTyped(CachingPipeline.getRenderScriptContext(), in.getType()); - bitmapIn.copyFrom(out); + Allocation bitmapIn = in; + if (copyOut) { + bitmapIn = Allocation.createTyped( + CachingPipeline.getRenderScriptContext(), in.getType()); + bitmapIn.copyFrom(out); + } environment.applyRepresentation(mBorder, bitmapIn, out); } } - public void applyFilters(int from, int to, Allocation in, Allocation out, FilterEnvironment environment) { + public void applyFilters(int from, int to, Allocation in, Allocation out, + FilterEnvironment environment) { if (mDoApplyFilters) { if (from < 0) { from = 0; @@ -605,4 +624,109 @@ public class ImagePreset { return usedFilters; } + public String getJsonString(String name) { + StringWriter swriter = new StringWriter(); + try { + JsonWriter writer = new JsonWriter(swriter); + writeJson(writer, name); + writer.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + return swriter.toString(); + } + + public void writeJson(JsonWriter writer, String name) { + int numFilters = mFilters.size(); + try { + writer.beginObject(); + writer.name(PRESET_NAME).value(name); + writer.name(mGeoData.getSerializationName()); + writer.beginObject(); + { + String[][] rep = mGeoData.serializeRepresentation(); + for (int i = 0; i < rep.length; i++) { + writer.name(rep[i][0]); + writer.value(rep[i][1]); + } + } + writer.endObject(); + + for (int i = 0; i < numFilters; i++) { + FilterRepresentation filter = mFilters.get(i); + String sname = filter.getSerializationName(); + writer.name(sname); + writer.beginObject(); + { + String[][] rep = filter.serializeRepresentation(); + for (int k = 0; k < rep.length; k++) { + writer.name(rep[k][0]); + writer.value(rep[k][1]); + } + } + writer.endObject(); + } + writer.endObject(); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + public boolean readJsonFromString(String filterString) { + StringReader sreader = new StringReader(filterString); + try { + JsonReader reader = new JsonReader(sreader); + boolean ok = readJson(reader); + if (!ok) { + return false; + } + reader.close(); + } catch (Exception e) { + e.printStackTrace(); + } + return true; + } + + public boolean readJson(JsonReader sreader) throws IOException { + sreader.beginObject(); + sreader.nextName(); + mName = sreader.nextString(); + + while (sreader.hasNext()) { + String name = sreader.nextName(); + + if (mGeoData.getSerializationName().equals(name)) { + mGeoData.deSerializeRepresentation(read(sreader)); + } else { + FilterRepresentation filter = creatFilterFromName(name); + if (filter == null) + return false; + filter.deSerializeRepresentation(read(sreader)); + addFilter(filter); + } + } + sreader.endObject(); + return true; + } + + FilterRepresentation creatFilterFromName(String name) { + FiltersManager filtersManager = FiltersManager.getManager(); + return filtersManager.createFilterFromName(name); + } + + String[][] read(JsonReader reader) throws IOException { + ArrayList <String[]> al = new ArrayList<String[]>(); + + reader.beginObject(); + + while (reader.hasNext()) { + String[]kv = { reader.nextName(),reader.nextString()}; + al.add(kv); + + } + reader.endObject(); + return al.toArray(new String[al.size()][]); + } } diff --git a/src/com/android/gallery3d/filtershow/presets/PipelineInterface.java b/src/com/android/gallery3d/filtershow/presets/PipelineInterface.java new file mode 100644 index 000000000..05f0a1aa8 --- /dev/null +++ b/src/com/android/gallery3d/filtershow/presets/PipelineInterface.java @@ -0,0 +1,31 @@ +/* + * 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.presets; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.support.v8.renderscript.Allocation; +import android.support.v8.renderscript.RenderScript; + +public interface PipelineInterface { + public String getName(); + public Resources getResources(); + public Allocation getInPixelsAllocation(); + public Allocation getOutPixelsAllocation(); + public boolean prepareRenderscriptAllocations(Bitmap bitmap); + public RenderScript getRSContext(); +} diff --git a/src/com/android/gallery3d/filtershow/tools/BitmapTask.java b/src/com/android/gallery3d/filtershow/tools/BitmapTask.java deleted file mode 100644 index 62801c1f2..000000000 --- a/src/com/android/gallery3d/filtershow/tools/BitmapTask.java +++ /dev/null @@ -1,68 +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.tools; - -import android.graphics.Bitmap; -import android.os.AsyncTask; - -/** - * Asynchronous task filtering or doign I/O with bitmaps. - */ -public class BitmapTask <T> extends AsyncTask<T, Void, Bitmap> { - - private Callbacks<T> mCallbacks; - private static final String LOGTAG = "BitmapTask"; - - public BitmapTask(Callbacks<T> callbacks) { - mCallbacks = callbacks; - } - - @Override - protected Bitmap doInBackground(T... params) { - if (params == null || mCallbacks == null) { - return null; - } - return mCallbacks.onExecute(params[0]); - } - - @Override - protected void onPostExecute(Bitmap result) { - if (mCallbacks == null) { - return; - } - mCallbacks.onComplete(result); - } - - @Override - protected void onCancelled() { - if (mCallbacks == null) { - return; - } - mCallbacks.onCancel(); - } - - /** - * Callbacks for the asynchronous task. - */ - public interface Callbacks<P> { - void onComplete(Bitmap result); - - void onCancel(); - - Bitmap onExecute(P param); - } -} diff --git a/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java b/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java index 008cb572c..2862be286 100644 --- a/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java +++ b/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java @@ -206,6 +206,8 @@ public class SaveCopyTask extends AsyncTask<ImagePreset, Void, Uri> { uri = insertContent(context, sourceUri, this.destinationFile, saveFileName, time); } + XmpPresets.writeFilterXMP(context, sourceUri, this.destinationFile, preset); + noBitmap = false; } catch (java.lang.OutOfMemoryError e) { // Try 5 times before failing for good. @@ -219,6 +221,7 @@ public class SaveCopyTask extends AsyncTask<ImagePreset, Void, Uri> { return uri; } + @Override protected void onPostExecute(Uri result) { if (callback != null) { diff --git a/src/com/android/gallery3d/filtershow/tools/XmpPresets.java b/src/com/android/gallery3d/filtershow/tools/XmpPresets.java new file mode 100644 index 000000000..be75f0253 --- /dev/null +++ b/src/com/android/gallery3d/filtershow/tools/XmpPresets.java @@ -0,0 +1,133 @@ +/* + * 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.tools; + +import android.content.Context; +import android.net.Uri; +import android.util.Log; + +import com.adobe.xmp.XMPException; +import com.adobe.xmp.XMPMeta; +import com.adobe.xmp.XMPMetaFactory; +import com.android.gallery3d.R; +import com.android.gallery3d.common.Utils; +import com.android.gallery3d.filtershow.imageshow.MasterImage; +import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.util.XmpUtilHelper; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.InputStream; + +public class XmpPresets { + public static final String + XMP_GOOGLE_FILTER_NAMESPACE = "http://ns.google.com/photos/1.0/filter/"; + public static final String XMP_GOOGLE_FILTER_PREFIX = "AFltr"; + public static final String XMP_SRC_FILE_URI = "SourceFileUri"; + public static final String XMP_FILTERSTACK = "filterstack"; + private static final String LOGTAG = "XmpPresets"; + + public static class XMresults { + public String presetString; + public ImagePreset preset; + public Uri originalimage; + } + + static { + try { + XMPMetaFactory.getSchemaRegistry().registerNamespace( + XMP_GOOGLE_FILTER_NAMESPACE, XMP_GOOGLE_FILTER_PREFIX); + } catch (XMPException e) { + Log.e(LOGTAG, "Register XMP name space failed", e); + } + } + + public static void writeFilterXMP( + Context context, Uri srcUri, File dstFile, ImagePreset preset) { + InputStream is = null; + XMPMeta xmpMeta = null; + try { + is = context.getContentResolver().openInputStream(srcUri); + xmpMeta = XmpUtilHelper.extractXMPMeta(is); + } catch (FileNotFoundException e) { + + } finally { + Utils.closeSilently(is); + } + + if (xmpMeta == null) { + xmpMeta = XMPMetaFactory.create(); + } + try { + xmpMeta.setProperty(XMP_GOOGLE_FILTER_NAMESPACE, + XMP_SRC_FILE_URI, srcUri.toString()); + xmpMeta.setProperty(XMP_GOOGLE_FILTER_NAMESPACE, + XMP_FILTERSTACK, preset.getJsonString(context.getString(R.string.saved))); + } catch (XMPException e) { + Log.v(LOGTAG, "Write XMP meta to file failed:" + dstFile.getAbsolutePath()); + return; + } + + if (!XmpUtilHelper.writeXMPMeta(dstFile.getAbsolutePath(), xmpMeta)) { + Log.v(LOGTAG, "Write XMP meta to file failed:" + dstFile.getAbsolutePath()); + } + } + + public static XMresults extractXMPData( + Context context, MasterImage mMasterImage, Uri uriToEdit) { + XMresults ret = new XMresults(); + + InputStream is = null; + XMPMeta xmpMeta = null; + try { + is = context.getContentResolver().openInputStream(uriToEdit); + xmpMeta = XmpUtilHelper.extractXMPMeta(is); + } catch (FileNotFoundException e) { + } finally { + Utils.closeSilently(is); + } + + if (xmpMeta == null) { + return null; + } + + try { + String strSrcUri = xmpMeta.getPropertyString(XMP_GOOGLE_FILTER_NAMESPACE, + XMP_SRC_FILE_URI); + + if (strSrcUri != null) { + String filterString = xmpMeta.getPropertyString(XMP_GOOGLE_FILTER_NAMESPACE, + XMP_FILTERSTACK); + + Uri srcUri = Uri.parse(strSrcUri); + ret.originalimage = srcUri; + + ret.preset = new ImagePreset(mMasterImage.getPreset()); + ret.presetString = filterString; + boolean ok = ret.preset.readJsonFromString(filterString); + if (!ok) { + return null; + } + return ret; + } + } catch (XMPException e) { + e.printStackTrace(); + } + + return null; + } +} diff --git a/src/com/android/gallery3d/filtershow/ui/ImageCurves.java b/src/com/android/gallery3d/filtershow/ui/ImageCurves.java index f7dcad7ce..0bab3954f 100644 --- a/src/com/android/gallery3d/filtershow/ui/ImageCurves.java +++ b/src/com/android/gallery3d/filtershow/ui/ImageCurves.java @@ -145,11 +145,6 @@ public class ImageCurves extends ImageShow { invalidate(); } - @Override - public boolean showTitle() { - return false; - } - private ImageFilterCurves curves() { String filterName = getFilterName(); ImagePreset p = getImagePreset(); @@ -221,7 +216,6 @@ public class ImageCurves extends ImageShow { getSpline(mCurrentCurveIndex) .draw(canvas, Spline.colorForCurve(mCurrentCurveIndex), getWidth(), getHeight(), true, mDoingTouchMove); - drawToast(canvas); } diff --git a/src/com/android/gallery3d/gadget/WidgetConfigure.java b/src/com/android/gallery3d/gadget/WidgetConfigure.java index eb81b6ef3..2a4c6cfe4 100644 --- a/src/com/android/gallery3d/gadget/WidgetConfigure.java +++ b/src/com/android/gallery3d/gadget/WidgetConfigure.java @@ -35,7 +35,7 @@ import com.android.gallery3d.data.DataManager; import com.android.gallery3d.data.LocalAlbum; import com.android.gallery3d.data.MediaSet; import com.android.gallery3d.data.Path; -import com.android.gallery3d.filtershow.FilterShowActivity; +import com.android.gallery3d.filtershow.crop.CropActivity; import com.android.gallery3d.filtershow.crop.CropExtras; public class WidgetConfigure extends Activity { @@ -149,7 +149,7 @@ public class WidgetConfigure extends Activity { int widgetHeight = Math.round(height * scale); mPickedItem = data.getData(); - Intent request = new Intent(FilterShowActivity.CROP_ACTION, mPickedItem) + Intent request = new Intent(CropActivity.CROP_ACTION, mPickedItem) .putExtra(CropExtras.KEY_OUTPUT_X, widgetWidth) .putExtra(CropExtras.KEY_OUTPUT_Y, widgetHeight) .putExtra(CropExtras.KEY_ASPECT_X, widgetWidth) diff --git a/src/com/android/gallery3d/ui/MenuExecutor.java b/src/com/android/gallery3d/ui/MenuExecutor.java index 8f4854e10..29def0527 100644 --- a/src/com/android/gallery3d/ui/MenuExecutor.java +++ b/src/com/android/gallery3d/ui/MenuExecutor.java @@ -190,7 +190,7 @@ public class MenuExecutor { setMenuItemVisible(menu, R.id.action_setas, supportSetAs); setMenuItemVisible(menu, R.id.action_show_on_map, supportShowOnMap); setMenuItemVisible(menu, R.id.action_edit, supportEdit); - // setMenuItemVisible(menu, R.id.action_simple_edit, supportEdit); + setMenuItemVisible(menu, R.id.action_simple_edit, supportEdit); setMenuItemVisible(menu, R.id.action_details, supportInfo); } diff --git a/src/com/android/gallery3d/util/SaveVideoFileUtils.java b/src/com/android/gallery3d/util/SaveVideoFileUtils.java index c281dd3e7..e2c5f51b9 100644 --- a/src/com/android/gallery3d/util/SaveVideoFileUtils.java +++ b/src/com/android/gallery3d/util/SaveVideoFileUtils.java @@ -19,6 +19,7 @@ package com.android.gallery3d.util; import android.content.ContentResolver; import android.content.ContentValues; import android.database.Cursor; +import android.media.MediaMetadataRetriever; import android.net.Uri; import android.os.Environment; import android.provider.MediaStore.Video; @@ -95,7 +96,7 @@ public class SaveVideoFileUtils { ContentResolver contentResolver, Uri uri ) { long nowInMs = System.currentTimeMillis(); long nowInSec = nowInMs / 1000; - final ContentValues values = new ContentValues(12); + final ContentValues values = new ContentValues(13); values.put(Video.Media.TITLE, mDstFileInfo.mFileName); values.put(Video.Media.DISPLAY_NAME, mDstFileInfo.mFile.getName()); values.put(Video.Media.MIME_TYPE, "video/mp4"); @@ -104,6 +105,8 @@ public class SaveVideoFileUtils { values.put(Video.Media.DATE_ADDED, nowInSec); values.put(Video.Media.DATA, mDstFileInfo.mFile.getAbsolutePath()); values.put(Video.Media.SIZE, mDstFileInfo.mFile.length()); + int durationMs = retriveVideoDurationMs(mDstFileInfo.mFile.getPath()); + values.put(Video.Media.DURATION, durationMs); // Copy the data taken and location info from src. String[] projection = new String[] { VideoColumns.DATE_TAKEN, @@ -138,4 +141,18 @@ public class SaveVideoFileUtils { return contentResolver.insert(Video.Media.EXTERNAL_CONTENT_URI, values); } + public static int retriveVideoDurationMs(String path) { + int durationMs = 0; + // Calculate the duration of the destination file. + MediaMetadataRetriever retriever = new MediaMetadataRetriever(); + retriever.setDataSource(path); + String duration = retriever.extractMetadata( + MediaMetadataRetriever.METADATA_KEY_DURATION); + if (duration != null) { + durationMs = Integer.parseInt(duration); + } + retriever.release(); + return durationMs; + } + } |