OSDN Git Service

Removed old crop.
authorRuben Brunk <rubenbrunk@google.com>
Thu, 6 Dec 2012 06:07:12 +0000 (22:07 -0800)
committerRuben Brunk <rubenbrunk@google.com>
Thu, 6 Dec 2012 20:25:39 +0000 (12:25 -0800)
Bug: 7441237
Change-Id: I29801f798a1d1ad3af81a82950edbb8a72ccae82

13 files changed:
AndroidManifest.xml
src/com/android/gallery3d/app/AlbumPage.java
src/com/android/gallery3d/app/CropImage.java [deleted file]
src/com/android/gallery3d/app/Wallpaper.java
src/com/android/gallery3d/filtershow/CropExtras.java [moved from src/com/android/gallery3d/data/CropExtras.java with 98% similarity]
src/com/android/gallery3d/filtershow/FilterShowActivity.java
src/com/android/gallery3d/filtershow/cache/ImageLoader.java
src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java
src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java
src/com/android/gallery3d/filtershow/imageshow/ImageCrop.java
src/com/android/gallery3d/gadget/WidgetConfigure.java
src/com/android/gallery3d/ui/CropView.java [deleted file]
src/com/android/gallery3d/ui/MenuExecutor.java

index 644a409..f2dac12 100644 (file)
             <meta-data android:name="android.wallpaper.preview"
                     android:resource="@xml/wallpaper_picker_preview" />
         </activity>
-        <activity android:name="com.android.gallery3d.app.CropImage"
-                android:configChanges="keyboardHidden|orientation|screenSize"
-                android:label="@string/crop_label"
-                android:process=":crop">
-            <intent-filter android:label="@string/crop_label">
-                <action android:name="com.android.camera.action.CROP" />
-                <data android:scheme="http" />
-                <data android:scheme="https" />
-                <data android:scheme="content" />
-                <data android:scheme="file" />
-                <data android:scheme="" />
-                <data android:mimeType="image/*" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.ALTERNATIVE" />
-                <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
-            </intent-filter>
-        </activity>
         <activity android:name="com.android.gallery3d.app.TrimVideo"
                 android:label="@string/trim_label">
         </activity>
                 <data android:mimeType="image/*" />
             </intent-filter>
             <intent-filter android:label="@string/crop_label">
-                <action android:name="com.android.camera.action.EDITOR_CROP" />
+                <action android:name="com.android.camera.action.CROP" />
                 <data android:scheme="http" />
                 <data android:scheme="https" />
                 <data android:scheme="content" />
index 50f5e02..6000090 100644 (file)
@@ -57,6 +57,9 @@ import com.android.gallery3d.ui.SynchronizedHandler;
 import com.android.gallery3d.util.Future;
 import com.android.gallery3d.util.GalleryUtils;
 import com.android.gallery3d.util.MediaSetUtils;
+import com.android.gallery3d.filtershow.FilterShowActivity;
+import com.android.gallery3d.filtershow.CropExtras;
+
 
 public class AlbumPage extends ActivityState implements GalleryActionBar.ClusterRunner,
         SelectionManager.SelectionListener, MediaSet.SyncListener, GalleryActionBar.OnAlbumModeSelectedListener {
@@ -317,11 +320,11 @@ public class AlbumPage extends ActivityState implements GalleryActionBar.Cluster
         if (mData.getString(Gallery.EXTRA_CROP) != null) {
             // TODO: Handle MtpImagew
             Uri uri = dm.getContentUri(item.getPath());
-            Intent intent = new Intent(CropImage.ACTION_CROP, uri)
+            Intent intent = new Intent(FilterShowActivity.CROP_ACTION, uri)
                     .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT)
                     .putExtras(getData());
             if (mData.getParcelable(MediaStore.EXTRA_OUTPUT) == null) {
-                intent.putExtra(CropImage.KEY_RETURN_DATA, true);
+                intent.putExtra(CropExtras.KEY_RETURN_DATA, true);
             }
             activity.startActivity(intent);
             activity.finish();
diff --git a/src/com/android/gallery3d/app/CropImage.java b/src/com/android/gallery3d/app/CropImage.java
deleted file mode 100644 (file)
index e7e95fd..0000000
+++ /dev/null
@@ -1,1040 +0,0 @@
-/*
- * Copyright (C) 2010 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.app;
-
-import android.annotation.TargetApi;
-import android.app.ProgressDialog;
-import android.app.WallpaperManager;
-import android.content.ContentValues;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.CompressFormat;
-import android.graphics.Bitmap.Config;
-import android.graphics.BitmapFactory;
-import android.graphics.BitmapRegionDecoder;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.MediaStore;
-import android.provider.MediaStore.Images;
-import android.util.FloatMath;
-import android.view.WindowManager;
-import android.widget.Toast;
-
-import com.actionbarsherlock.app.ActionBar;
-import com.actionbarsherlock.view.Menu;
-import com.actionbarsherlock.view.MenuItem;
-import com.actionbarsherlock.view.Window;
-import com.android.camera.Util;
-import com.android.gallery3d.R;
-import com.android.gallery3d.common.ApiHelper;
-import com.android.gallery3d.common.BitmapUtils;
-import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.data.DataManager;
-import com.android.gallery3d.data.LocalImage;
-import com.android.gallery3d.data.MediaItem;
-import com.android.gallery3d.data.MediaObject;
-import com.android.gallery3d.data.Path;
-import com.android.gallery3d.exif.ExifData;
-import com.android.gallery3d.exif.ExifOutputStream;
-import com.android.gallery3d.exif.ExifReader;
-import com.android.gallery3d.exif.ExifTag;
-import com.android.gallery3d.picasasource.PicasaSource;
-import com.android.gallery3d.ui.BitmapScreenNail;
-import com.android.gallery3d.ui.BitmapTileProvider;
-import com.android.gallery3d.ui.CropView;
-import com.android.gallery3d.ui.GLRoot;
-import com.android.gallery3d.ui.SynchronizedHandler;
-import com.android.gallery3d.ui.TileImageViewAdapter;
-import com.android.gallery3d.util.BucketNames;
-import com.android.gallery3d.util.Future;
-import com.android.gallery3d.util.FutureListener;
-import com.android.gallery3d.util.GalleryUtils;
-import com.android.gallery3d.util.InterruptableOutputStream;
-import com.android.gallery3d.util.ThreadPool.CancelListener;
-import com.android.gallery3d.util.ThreadPool.Job;
-import com.android.gallery3d.util.ThreadPool.JobContext;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.ByteOrder;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-/**
- * The activity can crop specific region of interest from an image.
- */
-public class CropImage extends AbstractGalleryActivity {
-    private static final String TAG = "CropImage";
-    public static final String ACTION_CROP = "com.android.camera.action.CROP";
-
-    private static final int MAX_PIXEL_COUNT = 5 * 1000000; // 5M pixels
-    private static final int MAX_FILE_INDEX = 1000;
-    private static final int TILE_SIZE = 512;
-    private static final int BACKUP_PIXEL_COUNT = 480000; // around 800x600
-
-    private static final int MSG_LARGE_BITMAP = 1;
-    private static final int MSG_BITMAP = 2;
-    private static final int MSG_SAVE_COMPLETE = 3;
-    private static final int MSG_SHOW_SAVE_ERROR = 4;
-    private static final int MSG_CANCEL_DIALOG = 5;
-
-    private static final int MAX_BACKUP_IMAGE_SIZE = 320;
-    private static final int DEFAULT_COMPRESS_QUALITY = 90;
-    private static final String TIME_STAMP_NAME = "'IMG'_yyyyMMdd_HHmmss";
-
-    public static final String KEY_RETURN_DATA = "return-data";
-    public static final String KEY_CROPPED_RECT = "cropped-rect";
-    public static final String KEY_ASPECT_X = "aspectX";
-    public static final String KEY_ASPECT_Y = "aspectY";
-    public static final String KEY_SPOTLIGHT_X = "spotlightX";
-    public static final String KEY_SPOTLIGHT_Y = "spotlightY";
-    public static final String KEY_OUTPUT_X = "outputX";
-    public static final String KEY_OUTPUT_Y = "outputY";
-    public static final String KEY_SCALE = "scale";
-    public static final String KEY_DATA = "data";
-    public static final String KEY_SCALE_UP_IF_NEEDED = "scaleUpIfNeeded";
-    public static final String KEY_OUTPUT_FORMAT = "outputFormat";
-    public static final String KEY_SET_AS_WALLPAPER = "set-as-wallpaper";
-    public static final String KEY_NO_FACE_DETECTION = "noFaceDetection";
-    public static final String KEY_SHOW_WHEN_LOCKED = "showWhenLocked";
-
-    private static final String KEY_STATE = "state";
-
-    private static final int STATE_INIT = 0;
-    private static final int STATE_LOADED = 1;
-    private static final int STATE_SAVING = 2;
-
-    public static final File DOWNLOAD_BUCKET = new File(
-            Environment.getExternalStorageDirectory(), BucketNames.DOWNLOAD);
-
-    public static final String CROP_ACTION = "com.android.camera.action.CROP";
-
-    private int mState = STATE_INIT;
-
-    private CropView mCropView;
-
-    private boolean mDoFaceDetection = true;
-
-    private Handler mMainHandler;
-
-    // We keep the following members so that we can free them
-
-    // mBitmap is the unrotated bitmap we pass in to mCropView for detect faces.
-    // mCropView is responsible for rotating it to the way that it is viewed by users.
-    private Bitmap mBitmap;
-    private BitmapTileProvider mBitmapTileProvider;
-    private BitmapRegionDecoder mRegionDecoder;
-    private Bitmap mBitmapInIntent;
-    private boolean mUseRegionDecoder = false;
-    private BitmapScreenNail mBitmapScreenNail;
-
-    private ProgressDialog mProgressDialog;
-    private Future<BitmapRegionDecoder> mLoadTask;
-    private Future<Bitmap> mLoadBitmapTask;
-    private Future<Intent> mSaveTask;
-
-    private MediaItem mMediaItem;
-
-    @Override
-    public void onCreate(Bundle bundle) {
-        super.onCreate(bundle);
-        requestWindowFeature(Window.FEATURE_ACTION_BAR);
-        requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
-
-        // Initialize UI
-        setContentView(R.layout.cropimage);
-        mCropView = new CropView(this);
-        getGLRoot().setContentPane(mCropView);
-
-        ActionBar actionBar = getSupportActionBar();
-        int displayOptions = ActionBar.DISPLAY_HOME_AS_UP
-                | ActionBar.DISPLAY_SHOW_TITLE;
-        actionBar.setDisplayOptions(displayOptions, displayOptions);
-
-        Bundle extra = getIntent().getExtras();
-        if (extra != null) {
-            if (extra.getBoolean(KEY_SET_AS_WALLPAPER, false)) {
-                actionBar.setTitle(getString(R.string.set_wallpaper));
-            }
-            if (extra.getBoolean(KEY_SHOW_WHEN_LOCKED, false)) {
-                getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
-            }
-        }
-
-        mMainHandler = new SynchronizedHandler(getGLRoot()) {
-            @Override
-            public void handleMessage(Message message) {
-                switch (message.what) {
-                    case MSG_LARGE_BITMAP: {
-                        dismissProgressDialogIfShown();
-                        onBitmapRegionDecoderAvailable((BitmapRegionDecoder) message.obj);
-                        break;
-                    }
-                    case MSG_BITMAP: {
-                        dismissProgressDialogIfShown();
-                        onBitmapAvailable((Bitmap) message.obj);
-                        break;
-                    }
-                    case MSG_SHOW_SAVE_ERROR: {
-                        dismissProgressDialogIfShown();
-                        setResult(RESULT_CANCELED);
-                        Toast.makeText(CropImage.this,
-                                CropImage.this.getString(R.string.save_error),
-                                Toast.LENGTH_LONG).show();
-                        finish();
-                    }
-                    case MSG_SAVE_COMPLETE: {
-                        dismissProgressDialogIfShown();
-                        setResult(RESULT_OK, (Intent) message.obj);
-                        finish();
-                        break;
-                    }
-                    case MSG_CANCEL_DIALOG: {
-                        setResult(RESULT_CANCELED);
-                        finish();
-                        break;
-                    }
-                }
-            }
-        };
-
-        setCropParameters();
-    }
-
-    @Override
-    protected void onSaveInstanceState(Bundle saveState) {
-        saveState.putInt(KEY_STATE, mState);
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        super.onCreateOptionsMenu(menu);
-        getSupportMenuInflater().inflate(R.menu.crop, menu);
-        return true;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case android.R.id.home: {
-                finish();
-                break;
-            }
-            case R.id.cancel: {
-                setResult(RESULT_CANCELED);
-                finish();
-                break;
-            }
-            case R.id.save: {
-                onSaveClicked();
-                break;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public void onBackPressed() {
-        finish();
-    }
-
-    private class SaveOutput implements Job<Intent> {
-        private final RectF mCropRect;
-
-        public SaveOutput(RectF cropRect) {
-            mCropRect = cropRect;
-        }
-
-        @Override
-        public Intent run(JobContext jc) {
-            RectF cropRect = mCropRect;
-            Bundle extra = getIntent().getExtras();
-
-            Rect rect = new Rect(
-                    Math.round(cropRect.left), Math.round(cropRect.top),
-                    Math.round(cropRect.right), Math.round(cropRect.bottom));
-
-            Intent result = new Intent();
-            result.putExtra(KEY_CROPPED_RECT, rect);
-            Bitmap cropped = null;
-            boolean outputted = false;
-            if (extra != null) {
-                Uri uri = (Uri) extra.getParcelable(MediaStore.EXTRA_OUTPUT);
-                if (uri != null) {
-                    if (jc.isCancelled()) return null;
-                    outputted = true;
-                    cropped = getCroppedImage(rect);
-                    if (!saveBitmapToUri(jc, cropped, uri)) return null;
-                }
-                if (extra.getBoolean(KEY_RETURN_DATA, false)) {
-                    if (jc.isCancelled()) return null;
-                    outputted = true;
-                    if (cropped == null) cropped = getCroppedImage(rect);
-                    result.putExtra(KEY_DATA, cropped);
-                }
-                if (extra.getBoolean(KEY_SET_AS_WALLPAPER, false)) {
-                    if (jc.isCancelled()) return null;
-                    outputted = true;
-                    if (cropped == null) cropped = getCroppedImage(rect);
-                    if (!setAsWallpaper(jc, cropped)) return null;
-                }
-            }
-            if (!outputted) {
-                if (jc.isCancelled()) return null;
-                if (cropped == null) cropped = getCroppedImage(rect);
-                Uri data = saveToMediaProvider(jc, cropped);
-                if (data != null) result.setData(data);
-            }
-            return result;
-        }
-    }
-
-    public static String determineCompressFormat(MediaObject obj) {
-        String compressFormat = "JPEG";
-        if (obj instanceof MediaItem) {
-            String mime = ((MediaItem) obj).getMimeType();
-            if (mime.contains("png") || mime.contains("gif")) {
-              // Set the compress format to PNG for png and gif images
-              // because they may contain alpha values.
-              compressFormat = "PNG";
-            }
-        }
-        return compressFormat;
-    }
-
-    private boolean setAsWallpaper(JobContext jc, Bitmap wallpaper) {
-        try {
-            WallpaperManager.getInstance(this).setBitmap(wallpaper);
-        } catch (IOException e) {
-            Log.w(TAG, "fail to set wall paper", e);
-        }
-        return true;
-    }
-
-    private File saveMedia(
-            JobContext jc, Bitmap cropped, File directory, String filename, ExifData exifData) {
-        // Try file-1.jpg, file-2.jpg, ... until we find a filename
-        // which does not exist yet.
-        File candidate = null;
-        String fileExtension = getFileExtension();
-        for (int i = 1; i < MAX_FILE_INDEX; ++i) {
-            candidate = new File(directory, filename + "-" + i + "."
-                    + fileExtension);
-            try {
-                if (candidate.createNewFile()) break;
-            } catch (IOException e) {
-                Log.e(TAG, "fail to create new file: "
-                        + candidate.getAbsolutePath(), e);
-                return null;
-            }
-        }
-        if (!candidate.exists() || !candidate.isFile()) {
-            throw new RuntimeException("cannot create file: " + filename);
-        }
-
-        candidate.setReadable(true, false);
-        candidate.setWritable(true, false);
-
-        try {
-            FileOutputStream fos = new FileOutputStream(candidate);
-            try {
-                if (exifData != null) {
-                    ExifOutputStream eos = new ExifOutputStream(fos);
-                    eos.setExifData(exifData);
-                    saveBitmapToOutputStream(jc, cropped,
-                            convertExtensionToCompressFormat(fileExtension), eos);
-                } else {
-                    saveBitmapToOutputStream(jc, cropped,
-                            convertExtensionToCompressFormat(fileExtension), fos);
-                }
-            } finally {
-                fos.close();
-            }
-        } catch (IOException e) {
-            Log.e(TAG, "fail to save image: "
-                    + candidate.getAbsolutePath(), e);
-            candidate.delete();
-            return null;
-        }
-
-        if (jc.isCancelled()) {
-            candidate.delete();
-            return null;
-        }
-
-        return candidate;
-    }
-
-    private ExifData getExifData(String path) {
-        FileInputStream is = null;
-        try {
-            is = new FileInputStream(path);
-            ExifReader reader = new ExifReader();
-            ExifData data = reader.read(is);
-            return data;
-        } catch (Throwable t) {
-            Log.w(TAG, "Cannot read EXIF data", t);
-            return null;
-        } finally {
-            Util.closeSilently(is);
-        }
-    }
-
-    private static final String EXIF_SOFTWARE_VALUE = "Android Gallery";
-
-    private void changeExifData(ExifData data, int width, int height) {
-        data.addTag(ExifTag.TAG_IMAGE_WIDTH).setValue(width);
-        data.addTag(ExifTag.TAG_IMAGE_LENGTH).setValue(height);
-        data.addTag(ExifTag.TAG_SOFTWARE).setValue(EXIF_SOFTWARE_VALUE);
-        data.addTag(ExifTag.TAG_DATE_TIME).setTimeValue(System.currentTimeMillis());
-        // Remove the original thumbnail
-        // TODO: generate a new thumbnail for the cropped image.
-        data.removeThumbnailData();
-    }
-
-    private Uri saveToMediaProvider(JobContext jc, Bitmap cropped) {
-        if (PicasaSource.isPicasaImage(mMediaItem)) {
-            return savePicasaImage(jc, cropped);
-        } else if (mMediaItem instanceof LocalImage) {
-            return saveLocalImage(jc, cropped);
-        } else {
-            return saveGenericImage(jc, cropped);
-        }
-    }
-
-    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
-    private static void setImageSize(ContentValues values, int width, int height) {
-        // The two fields are available since ICS but got published in JB
-        if (ApiHelper.HAS_MEDIA_COLUMNS_WIDTH_AND_HEIGHT) {
-            values.put(Images.Media.WIDTH, width);
-            values.put(Images.Media.HEIGHT, height);
-        }
-    }
-
-    private Uri savePicasaImage(JobContext jc, Bitmap cropped) {
-        if (!DOWNLOAD_BUCKET.isDirectory() && !DOWNLOAD_BUCKET.mkdirs()) {
-            throw new RuntimeException("cannot create download folder");
-        }
-        String filename = PicasaSource.getImageTitle(mMediaItem);
-        int pos = filename.lastIndexOf('.');
-        if (pos >= 0) filename = filename.substring(0, pos);
-        ExifData exifData = new ExifData(ByteOrder.BIG_ENDIAN);
-        PicasaSource.extractExifValues(mMediaItem, exifData);
-        changeExifData(exifData, cropped.getWidth(), cropped.getHeight());
-        File output = saveMedia(jc, cropped, DOWNLOAD_BUCKET, filename, exifData);
-        if (output == null) return null;
-
-        long now = System.currentTimeMillis() / 1000;
-        ContentValues values = new ContentValues();
-        values.put(Images.Media.TITLE, PicasaSource.getImageTitle(mMediaItem));
-        values.put(Images.Media.DISPLAY_NAME, output.getName());
-        values.put(Images.Media.DATE_TAKEN, PicasaSource.getDateTaken(mMediaItem));
-        values.put(Images.Media.DATE_MODIFIED, now);
-        values.put(Images.Media.DATE_ADDED, now);
-        values.put(Images.Media.MIME_TYPE, getOutputMimeType());
-        values.put(Images.Media.ORIENTATION, 0);
-        values.put(Images.Media.DATA, output.getAbsolutePath());
-        values.put(Images.Media.SIZE, output.length());
-        setImageSize(values, cropped.getWidth(), cropped.getHeight());
-
-        double latitude = PicasaSource.getLatitude(mMediaItem);
-        double longitude = PicasaSource.getLongitude(mMediaItem);
-        if (GalleryUtils.isValidLocation(latitude, longitude)) {
-            values.put(Images.Media.LATITUDE, latitude);
-            values.put(Images.Media.LONGITUDE, longitude);
-        }
-        return getContentResolver().insert(
-                Images.Media.EXTERNAL_CONTENT_URI, values);
-    }
-
-    private Uri saveLocalImage(JobContext jc, Bitmap cropped) {
-        LocalImage localImage = (LocalImage) mMediaItem;
-
-        File oldPath = new File(localImage.filePath);
-        File directory = new File(oldPath.getParent());
-
-        String filename = oldPath.getName();
-        int pos = filename.lastIndexOf('.');
-        if (pos >= 0) filename = filename.substring(0, pos);
-        File output = null;
-
-        ExifData exifData = null;
-        if (convertExtensionToCompressFormat(getFileExtension()) == CompressFormat.JPEG) {
-            exifData = getExifData(oldPath.getAbsolutePath());
-            if (exifData != null) {
-                changeExifData(exifData, cropped.getWidth(), cropped.getHeight());
-            }
-        }
-        output = saveMedia(jc, cropped, directory, filename, exifData);
-        if (output == null) return null;
-
-        long now = System.currentTimeMillis() / 1000;
-        ContentValues values = new ContentValues();
-        values.put(Images.Media.TITLE, localImage.caption);
-        values.put(Images.Media.DISPLAY_NAME, output.getName());
-        values.put(Images.Media.DATE_TAKEN, localImage.dateTakenInMs);
-        values.put(Images.Media.DATE_MODIFIED, now);
-        values.put(Images.Media.DATE_ADDED, now);
-        values.put(Images.Media.MIME_TYPE, getOutputMimeType());
-        values.put(Images.Media.ORIENTATION, 0);
-        values.put(Images.Media.DATA, output.getAbsolutePath());
-        values.put(Images.Media.SIZE, output.length());
-
-        setImageSize(values, cropped.getWidth(), cropped.getHeight());
-
-        if (GalleryUtils.isValidLocation(localImage.latitude, localImage.longitude)) {
-            values.put(Images.Media.LATITUDE, localImage.latitude);
-            values.put(Images.Media.LONGITUDE, localImage.longitude);
-        }
-        return getContentResolver().insert(
-                Images.Media.EXTERNAL_CONTENT_URI, values);
-    }
-
-    private Uri saveGenericImage(JobContext jc, Bitmap cropped) {
-        if (!DOWNLOAD_BUCKET.isDirectory() && !DOWNLOAD_BUCKET.mkdirs()) {
-            throw new RuntimeException("cannot create download folder");
-        }
-
-        long now = System.currentTimeMillis();
-        String filename = new SimpleDateFormat(TIME_STAMP_NAME).
-                format(new Date(now));
-
-        File output = saveMedia(jc, cropped, DOWNLOAD_BUCKET, filename, null);
-        if (output == null) return null;
-
-        ContentValues values = new ContentValues();
-        values.put(Images.Media.TITLE, filename);
-        values.put(Images.Media.DISPLAY_NAME, output.getName());
-        values.put(Images.Media.DATE_TAKEN, now);
-        values.put(Images.Media.DATE_MODIFIED, now / 1000);
-        values.put(Images.Media.DATE_ADDED, now / 1000);
-        values.put(Images.Media.MIME_TYPE, getOutputMimeType());
-        values.put(Images.Media.ORIENTATION, 0);
-        values.put(Images.Media.DATA, output.getAbsolutePath());
-        values.put(Images.Media.SIZE, output.length());
-
-        setImageSize(values, cropped.getWidth(), cropped.getHeight());
-
-        return getContentResolver().insert(
-                Images.Media.EXTERNAL_CONTENT_URI, values);
-    }
-
-    private boolean saveBitmapToOutputStream(
-            JobContext jc, Bitmap bitmap, CompressFormat format, OutputStream os) {
-        // We wrap the OutputStream so that it can be interrupted.
-        final InterruptableOutputStream ios = new InterruptableOutputStream(os);
-        jc.setCancelListener(new CancelListener() {
-                @Override
-                public void onCancel() {
-                    ios.interrupt();
-                }
-            });
-        try {
-            bitmap.compress(format, DEFAULT_COMPRESS_QUALITY, ios);
-            return !jc.isCancelled();
-        } finally {
-            jc.setCancelListener(null);
-            Utils.closeSilently(ios);
-        }
-    }
-
-    private boolean saveBitmapToUri(JobContext jc, Bitmap bitmap, Uri uri) {
-        try {
-            OutputStream out = getContentResolver().openOutputStream(uri);
-            try {
-                return saveBitmapToOutputStream(jc, bitmap,
-                        convertExtensionToCompressFormat(getFileExtension()), out);
-            } finally {
-                Utils.closeSilently(out);
-            }
-        } catch (FileNotFoundException e) {
-            Log.w(TAG, "cannot write output", e);
-        }
-        return true;
-    }
-
-    private CompressFormat convertExtensionToCompressFormat(String extension) {
-        return extension.equals("png")
-                ? CompressFormat.PNG
-                : CompressFormat.JPEG;
-    }
-
-    private String getOutputMimeType() {
-        return getFileExtension().equals("png") ? "image/png" : "image/jpeg";
-    }
-
-    private String getFileExtension() {
-        String requestFormat = getIntent().getStringExtra(KEY_OUTPUT_FORMAT);
-        String outputFormat = (requestFormat == null)
-                ? determineCompressFormat(mMediaItem)
-                : requestFormat;
-
-        outputFormat = outputFormat.toLowerCase();
-        return (outputFormat.equals("png") || outputFormat.equals("gif"))
-                ? "png" // We don't support gif compression.
-                : "jpg";
-    }
-
-    private void onSaveClicked() {
-        Bundle extra = getIntent().getExtras();
-        RectF cropRect = mCropView.getCropRectangle();
-        if (cropRect == null) return;
-        mState = STATE_SAVING;
-        int messageId = extra != null && extra.getBoolean(KEY_SET_AS_WALLPAPER)
-                ? R.string.wallpaper
-                : R.string.saving_image;
-        mProgressDialog = ProgressDialog.show(
-                this, null, getString(messageId), true, false);
-        mSaveTask = getThreadPool().submit(new SaveOutput(cropRect),
-                new FutureListener<Intent>() {
-            @Override
-            public void onFutureDone(Future<Intent> future) {
-                mSaveTask = null;
-                if (future.isCancelled()) return;
-                Intent intent = future.get();
-                if (intent != null) {
-                    mMainHandler.sendMessage(mMainHandler.obtainMessage(
-                            MSG_SAVE_COMPLETE, intent));
-                } else {
-                    mMainHandler.sendEmptyMessage(MSG_SHOW_SAVE_ERROR);
-                }
-            }
-        });
-    }
-
-    private Bitmap getCroppedImage(Rect rect) {
-        Utils.assertTrue(rect.width() > 0 && rect.height() > 0);
-
-        Bundle extras = getIntent().getExtras();
-        // (outputX, outputY) = the width and height of the returning bitmap.
-        int outputX = rect.width();
-        int outputY = rect.height();
-        if (extras != null) {
-            outputX = extras.getInt(KEY_OUTPUT_X, outputX);
-            outputY = extras.getInt(KEY_OUTPUT_Y, outputY);
-        }
-
-        if (outputX * outputY > MAX_PIXEL_COUNT) {
-            float scale = FloatMath.sqrt((float) MAX_PIXEL_COUNT / outputX / outputY);
-            Log.w(TAG, "scale down the cropped image: " + scale);
-            outputX = Math.round(scale * outputX);
-            outputY = Math.round(scale * outputY);
-        }
-
-        // (rect.width() * scaleX, rect.height() * scaleY) =
-        // the size of drawing area in output bitmap
-        float scaleX = 1;
-        float scaleY = 1;
-        Rect dest = new Rect(0, 0, outputX, outputY);
-        if (extras == null || extras.getBoolean(KEY_SCALE, true)) {
-            scaleX = (float) outputX / rect.width();
-            scaleY = (float) outputY / rect.height();
-            if (extras == null || !extras.getBoolean(
-                    KEY_SCALE_UP_IF_NEEDED, false)) {
-                if (scaleX > 1f) scaleX = 1;
-                if (scaleY > 1f) scaleY = 1;
-            }
-        }
-
-        // Keep the content in the center (or crop the content)
-        int rectWidth = Math.round(rect.width() * scaleX);
-        int rectHeight = Math.round(rect.height() * scaleY);
-        dest.set(Math.round((outputX - rectWidth) / 2f),
-                Math.round((outputY - rectHeight) / 2f),
-                Math.round((outputX + rectWidth) / 2f),
-                Math.round((outputY + rectHeight) / 2f));
-
-        if (mBitmapInIntent != null) {
-            Bitmap source = mBitmapInIntent;
-            Bitmap result = Bitmap.createBitmap(
-                    outputX, outputY, Config.ARGB_8888);
-            Canvas canvas = new Canvas(result);
-            canvas.drawBitmap(source, rect, dest, null);
-            return result;
-        }
-
-        if (mUseRegionDecoder) {
-            int rotation = mMediaItem.getFullImageRotation();
-            rotateRectangle(rect, mCropView.getImageWidth(),
-                    mCropView.getImageHeight(), 360 - rotation);
-            rotateRectangle(dest, outputX, outputY, 360 - rotation);
-
-            BitmapFactory.Options options = new BitmapFactory.Options();
-            int sample = BitmapUtils.computeSampleSizeLarger(
-                    Math.max(scaleX, scaleY));
-            options.inSampleSize = sample;
-
-            // The decoding result is what we want if
-            //   1. The size of the decoded bitmap match the destination's size
-            //   2. The destination covers the whole output bitmap
-            //   3. No rotation
-            if ((rect.width() / sample) == dest.width()
-                    && (rect.height() / sample) == dest.height()
-                    && (outputX == dest.width()) && (outputY == dest.height())
-                    && rotation == 0) {
-                // To prevent concurrent access in GLThread
-                synchronized (mRegionDecoder) {
-                    return mRegionDecoder.decodeRegion(rect, options);
-                }
-            }
-            Bitmap result = Bitmap.createBitmap(
-                    outputX, outputY, Config.ARGB_8888);
-            Canvas canvas = new Canvas(result);
-            rotateCanvas(canvas, outputX, outputY, rotation);
-            drawInTiles(canvas, mRegionDecoder, rect, dest, sample);
-            return result;
-        } else {
-            int rotation = mMediaItem.getRotation();
-            rotateRectangle(rect, mCropView.getImageWidth(),
-                    mCropView.getImageHeight(), 360 - rotation);
-            rotateRectangle(dest, outputX, outputY, 360 - rotation);
-            Bitmap result = Bitmap.createBitmap(outputX, outputY, Config.ARGB_8888);
-            Canvas canvas = new Canvas(result);
-            rotateCanvas(canvas, outputX, outputY, rotation);
-            canvas.drawBitmap(mBitmap,
-                    rect, dest, new Paint(Paint.FILTER_BITMAP_FLAG));
-            return result;
-        }
-    }
-
-    private static void rotateCanvas(
-            Canvas canvas, int width, int height, int rotation) {
-        canvas.translate(width / 2, height / 2);
-        canvas.rotate(rotation);
-        if (((rotation / 90) & 0x01) == 0) {
-            canvas.translate(-width / 2, -height / 2);
-        } else {
-            canvas.translate(-height / 2, -width / 2);
-        }
-    }
-
-    private static void rotateRectangle(
-            Rect rect, int width, int height, int rotation) {
-        if (rotation == 0 || rotation == 360) return;
-
-        int w = rect.width();
-        int h = rect.height();
-        switch (rotation) {
-            case 90: {
-                rect.top = rect.left;
-                rect.left = height - rect.bottom;
-                rect.right = rect.left + h;
-                rect.bottom = rect.top + w;
-                return;
-            }
-            case 180: {
-                rect.left = width - rect.right;
-                rect.top = height - rect.bottom;
-                rect.right = rect.left + w;
-                rect.bottom = rect.top + h;
-                return;
-            }
-            case 270: {
-                rect.left = rect.top;
-                rect.top = width - rect.right;
-                rect.right = rect.left + h;
-                rect.bottom = rect.top + w;
-                return;
-            }
-            default: throw new AssertionError();
-        }
-    }
-
-    private void drawInTiles(Canvas canvas,
-            BitmapRegionDecoder decoder, Rect rect, Rect dest, int sample) {
-        int tileSize = TILE_SIZE * sample;
-        Rect tileRect = new Rect();
-        BitmapFactory.Options options = new BitmapFactory.Options();
-        options.inPreferredConfig = Config.ARGB_8888;
-        options.inSampleSize = sample;
-        canvas.translate(dest.left, dest.top);
-        canvas.scale((float) sample * dest.width() / rect.width(),
-                (float) sample * dest.height() / rect.height());
-        Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
-        for (int tx = rect.left, x = 0;
-                tx < rect.right; tx += tileSize, x += TILE_SIZE) {
-            for (int ty = rect.top, y = 0;
-                    ty < rect.bottom; ty += tileSize, y += TILE_SIZE) {
-                tileRect.set(tx, ty, tx + tileSize, ty + tileSize);
-                if (tileRect.intersect(rect)) {
-                    Bitmap bitmap;
-
-                    // To prevent concurrent access in GLThread
-                    synchronized (decoder) {
-                        bitmap = decoder.decodeRegion(tileRect, options);
-                    }
-                    canvas.drawBitmap(bitmap, x, y, paint);
-                    bitmap.recycle();
-                }
-            }
-        }
-    }
-
-    private void onBitmapRegionDecoderAvailable(
-            BitmapRegionDecoder regionDecoder) {
-
-        if (regionDecoder == null) {
-            Toast.makeText(this, R.string.fail_to_load_image, Toast.LENGTH_SHORT).show();
-            finish();
-            return;
-        }
-        mRegionDecoder = regionDecoder;
-        mUseRegionDecoder = true;
-        mState = STATE_LOADED;
-
-        BitmapFactory.Options options = new BitmapFactory.Options();
-        int width = regionDecoder.getWidth();
-        int height = regionDecoder.getHeight();
-        options.inSampleSize = BitmapUtils.computeSampleSize(width, height,
-                BitmapUtils.UNCONSTRAINED, BACKUP_PIXEL_COUNT);
-        mBitmap = regionDecoder.decodeRegion(
-                new Rect(0, 0, width, height), options);
-
-        mBitmapScreenNail = new BitmapScreenNail(mBitmap);
-
-        TileImageViewAdapter adapter = new TileImageViewAdapter();
-        adapter.setScreenNail(mBitmapScreenNail, width, height);
-        adapter.setRegionDecoder(regionDecoder);
-
-        mCropView.setDataModel(adapter, mMediaItem.getFullImageRotation());
-        if (mDoFaceDetection) {
-            mCropView.detectFaces(mBitmap);
-        } else {
-            mCropView.initializeHighlightRectangle();
-        }
-    }
-
-    private void onBitmapAvailable(Bitmap bitmap) {
-        if (bitmap == null) {
-            Toast.makeText(this, R.string.fail_to_load_image, Toast.LENGTH_SHORT).show();
-            finish();
-            return;
-        }
-        mUseRegionDecoder = false;
-        mState = STATE_LOADED;
-
-        mBitmap = bitmap;
-        BitmapFactory.Options options = new BitmapFactory.Options();
-        mCropView.setDataModel(new BitmapTileProvider(bitmap, 512),
-                mMediaItem.getRotation());
-        if (mDoFaceDetection) {
-            mCropView.detectFaces(bitmap);
-        } else {
-            mCropView.initializeHighlightRectangle();
-        }
-    }
-
-    private void setCropParameters() {
-        Bundle extras = getIntent().getExtras();
-        if (extras == null)
-            return;
-        int aspectX = extras.getInt(KEY_ASPECT_X, 0);
-        int aspectY = extras.getInt(KEY_ASPECT_Y, 0);
-        if (aspectX != 0 && aspectY != 0) {
-            mCropView.setAspectRatio((float) aspectX / aspectY);
-        }
-
-        float spotlightX = extras.getFloat(KEY_SPOTLIGHT_X, 0);
-        float spotlightY = extras.getFloat(KEY_SPOTLIGHT_Y, 0);
-        if (spotlightX != 0 && spotlightY != 0) {
-            mCropView.setSpotlightRatio(spotlightX, spotlightY);
-        }
-    }
-
-    private void initializeData() {
-        Bundle extras = getIntent().getExtras();
-
-        if (extras != null) {
-            if (extras.containsKey(KEY_NO_FACE_DETECTION)) {
-                mDoFaceDetection = !extras.getBoolean(KEY_NO_FACE_DETECTION);
-            }
-
-            mBitmapInIntent = extras.getParcelable(KEY_DATA);
-
-            if (mBitmapInIntent != null) {
-                mBitmapTileProvider =
-                        new BitmapTileProvider(mBitmapInIntent, MAX_BACKUP_IMAGE_SIZE);
-                mCropView.setDataModel(mBitmapTileProvider, 0);
-                if (mDoFaceDetection) {
-                    mCropView.detectFaces(mBitmapInIntent);
-                } else {
-                    mCropView.initializeHighlightRectangle();
-                }
-                mState = STATE_LOADED;
-                return;
-            }
-        }
-
-        mProgressDialog = ProgressDialog.show(
-                this, null, getString(R.string.loading_image), true, true);
-        mProgressDialog.setCanceledOnTouchOutside(false);
-        mProgressDialog.setCancelMessage(mMainHandler.obtainMessage(MSG_CANCEL_DIALOG));
-
-        mMediaItem = getMediaItemFromIntentData();
-        if (mMediaItem == null) return;
-
-        boolean supportedByBitmapRegionDecoder =
-            (mMediaItem.getSupportedOperations() & MediaItem.SUPPORT_FULL_IMAGE) != 0;
-        if (supportedByBitmapRegionDecoder) {
-            mLoadTask = getThreadPool().submit(new LoadDataTask(mMediaItem),
-                    new FutureListener<BitmapRegionDecoder>() {
-                @Override
-                public void onFutureDone(Future<BitmapRegionDecoder> future) {
-                    mLoadTask = null;
-                    BitmapRegionDecoder decoder = future.get();
-                    if (future.isCancelled()) {
-                        if (decoder != null) decoder.recycle();
-                        return;
-                    }
-                    mMainHandler.sendMessage(mMainHandler.obtainMessage(
-                            MSG_LARGE_BITMAP, decoder));
-                }
-            });
-        } else {
-            mLoadBitmapTask = getThreadPool().submit(new LoadBitmapDataTask(mMediaItem),
-                    new FutureListener<Bitmap>() {
-                @Override
-                public void onFutureDone(Future<Bitmap> future) {
-                    mLoadBitmapTask = null;
-                    Bitmap bitmap = future.get();
-                    if (future.isCancelled()) {
-                        if (bitmap != null) bitmap.recycle();
-                        return;
-                    }
-                    mMainHandler.sendMessage(mMainHandler.obtainMessage(
-                            MSG_BITMAP, bitmap));
-                }
-            });
-        }
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        if (mState == STATE_INIT) initializeData();
-        if (mState == STATE_SAVING) onSaveClicked();
-
-        // TODO: consider to do it in GLView system
-        GLRoot root = getGLRoot();
-        root.lockRenderThread();
-        try {
-            mCropView.resume();
-        } finally {
-            root.unlockRenderThread();
-        }
-    }
-
-    @Override
-    protected void onPause() {
-        super.onPause();
-        dismissProgressDialogIfShown();
-
-        Future<BitmapRegionDecoder> loadTask = mLoadTask;
-        if (loadTask != null && !loadTask.isDone()) {
-            // load in progress, try to cancel it
-            loadTask.cancel();
-            loadTask.waitDone();
-        }
-
-        Future<Bitmap> loadBitmapTask = mLoadBitmapTask;
-        if (loadBitmapTask != null && !loadBitmapTask.isDone()) {
-            // load in progress, try to cancel it
-            loadBitmapTask.cancel();
-            loadBitmapTask.waitDone();
-        }
-
-        Future<Intent> saveTask = mSaveTask;
-        if (saveTask != null && !saveTask.isDone()) {
-            // save in progress, try to cancel it
-            saveTask.cancel();
-            saveTask.waitDone();
-        }
-        GLRoot root = getGLRoot();
-        root.lockRenderThread();
-        try {
-            mCropView.pause();
-        } finally {
-            root.unlockRenderThread();
-        }
-    }
-
-    @Override
-    protected void onDestroy() {
-        super.onDestroy();
-        if (mBitmapScreenNail != null) {
-            mBitmapScreenNail.recycle();
-            mBitmapScreenNail = null;
-        }
-    }
-
-    private void dismissProgressDialogIfShown() {
-        if (mProgressDialog != null) {
-            mProgressDialog.dismiss();
-            mProgressDialog = null;
-        }
-    }
-
-    private MediaItem getMediaItemFromIntentData() {
-        Uri uri = getIntent().getData();
-        DataManager manager = getDataManager();
-        Path path = manager.findPathByUri(uri, getIntent().getType());
-        if (path == null) {
-            Log.w(TAG, "cannot get path for: " + uri + ", or no data given");
-            return null;
-        }
-        return (MediaItem) manager.getMediaObject(path);
-    }
-
-    private class LoadDataTask implements Job<BitmapRegionDecoder> {
-        MediaItem mItem;
-
-        public LoadDataTask(MediaItem item) {
-            mItem = item;
-        }
-
-        @Override
-        public BitmapRegionDecoder run(JobContext jc) {
-            return mItem == null ? null : mItem.requestLargeImage().run(jc);
-        }
-    }
-
-    private class LoadBitmapDataTask implements Job<Bitmap> {
-        MediaItem mItem;
-
-        public LoadBitmapDataTask(MediaItem item) {
-            mItem = item;
-        }
-        @Override
-        public Bitmap run(JobContext jc) {
-            return mItem == null
-                    ? null
-                    : mItem.requestImage(MediaItem.TYPE_THUMBNAIL).run(jc);
-        }
-    }
-}
index fce4bac..1bbe8d2 100644 (file)
@@ -27,6 +27,7 @@ import android.view.Display;
 
 import com.android.gallery3d.common.ApiHelper;
 import com.android.gallery3d.filtershow.FilterShowActivity;
+import com.android.gallery3d.filtershow.CropExtras;
 
 /**
  * Wallpaper picker for the gallery application. This just redirects to the
@@ -102,16 +103,15 @@ public class Wallpaper extends Activity {
                 Intent request = new Intent(FilterShowActivity.CROP_ACTION)
                         .setDataAndType(mPickedItem, IMAGE_TYPE)
                         .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT)
-                        .putExtra(CropImage.KEY_OUTPUT_X, width)
-                        .putExtra(CropImage.KEY_OUTPUT_Y, height)
-                        .putExtra(CropImage.KEY_ASPECT_X, width)
-                        .putExtra(CropImage.KEY_ASPECT_Y, height)
-                        .putExtra(CropImage.KEY_SPOTLIGHT_X, spotlightX)
-                        .putExtra(CropImage.KEY_SPOTLIGHT_Y, spotlightY)
-                        .putExtra(CropImage.KEY_SCALE, true)
-                        .putExtra(CropImage.KEY_SCALE_UP_IF_NEEDED, true)
-                        .putExtra(CropImage.KEY_NO_FACE_DETECTION, true)
-                        .putExtra(CropImage.KEY_SET_AS_WALLPAPER, true);
+                        .putExtra(CropExtras.KEY_OUTPUT_X, width)
+                        .putExtra(CropExtras.KEY_OUTPUT_Y, height)
+                        .putExtra(CropExtras.KEY_ASPECT_X, width)
+                        .putExtra(CropExtras.KEY_ASPECT_Y, height)
+                        .putExtra(CropExtras.KEY_SPOTLIGHT_X, spotlightX)
+                        .putExtra(CropExtras.KEY_SPOTLIGHT_Y, spotlightY)
+                        .putExtra(CropExtras.KEY_SCALE, true)
+                        .putExtra(CropExtras.KEY_SCALE_UP_IF_NEEDED, true)
+                        .putExtra(CropExtras.KEY_SET_AS_WALLPAPER, true);
                 startActivity(request);
                 finish();
             }
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.gallery3d.data;
+package com.android.gallery3d.filtershow;
 
 import android.net.Uri;
 
index 9cc3b6e..cf10a3e 100644 (file)
@@ -54,7 +54,6 @@ import android.widget.ShareActionProvider.OnShareTargetSelectedListener;
 import android.widget.Toast;
 
 import com.android.gallery3d.R;
-import com.android.gallery3d.data.CropExtras;
 import com.android.gallery3d.data.LocalAlbum;
 import com.android.gallery3d.filtershow.cache.ImageLoader;
 import com.android.gallery3d.filtershow.filters.ImageFilter;
@@ -103,7 +102,7 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
         OnShareTargetSelectedListener {
 
     // fields for supporting crop action
-    public static final String CROP_ACTION = "com.android.camera.action.EDITOR_CROP";
+    public static final String CROP_ACTION = "com.android.camera.action.CROP";
     private CropExtras mCropExtras = null;
 
     public static final String TINY_PLANET_ACTION = "com.android.camera.action.TINY_PLANET";
index 0af152c..a1a1ba1 100644 (file)
@@ -38,10 +38,10 @@ import com.adobe.xmp.XMPMeta;
 
 import com.android.gallery3d.R;
 import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.data.CropExtras;
 import com.android.gallery3d.exif.ExifInvalidFormatException;
 import com.android.gallery3d.exif.ExifParser;
 import com.android.gallery3d.exif.ExifTag;
+import com.android.gallery3d.filtershow.CropExtras;
 import com.android.gallery3d.filtershow.FilterShowActivity;
 import com.android.gallery3d.filtershow.HistoryAdapter;
 import com.android.gallery3d.filtershow.imageshow.ImageCrop;
index 2917717..33ecc8a 100644 (file)
@@ -23,7 +23,7 @@ import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.RectF;
 
-import com.android.gallery3d.data.CropExtras;
+import com.android.gallery3d.filtershow.CropExtras;
 import com.android.gallery3d.filtershow.imageshow.GeometryMath;
 import com.android.gallery3d.filtershow.imageshow.GeometryMetadata;
 
index 5f32515..b532840 100644 (file)
@@ -21,7 +21,7 @@ import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.RectF;
 
-import com.android.gallery3d.data.CropExtras;
+import com.android.gallery3d.filtershow.CropExtras;
 import com.android.gallery3d.filtershow.cache.ImageLoader;
 import com.android.gallery3d.filtershow.filters.ImageFilterGeometry;
 
index 84ddaa3..594e008 100644 (file)
@@ -29,7 +29,7 @@ import android.util.AttributeSet;
 import android.util.Log;
 
 import com.android.gallery3d.R;
-import com.android.gallery3d.data.CropExtras;
+import com.android.gallery3d.filtershow.CropExtras;
 
 public class ImageCrop extends ImageGeometry {
     private static final boolean LOGV = false;
index b58de72..3a1b52b 100644 (file)
@@ -27,10 +27,10 @@ import android.widget.RemoteViews;
 
 import com.android.gallery3d.R;
 import com.android.gallery3d.app.AlbumPicker;
-import com.android.gallery3d.app.CropImage;
 import com.android.gallery3d.app.DialogPicker;
 import com.android.gallery3d.common.ApiHelper;
 import com.android.gallery3d.filtershow.FilterShowActivity;
+import com.android.gallery3d.filtershow.CropExtras;
 
 public class WidgetConfigure extends Activity {
     @SuppressWarnings("unused")
@@ -144,13 +144,13 @@ public class WidgetConfigure extends Activity {
 
         mPickedItem = data.getData();
         Intent request = new Intent(FilterShowActivity.CROP_ACTION, mPickedItem)
-                .putExtra(CropImage.KEY_OUTPUT_X, widgetWidth)
-                .putExtra(CropImage.KEY_OUTPUT_Y, widgetHeight)
-                .putExtra(CropImage.KEY_ASPECT_X, widgetWidth)
-                .putExtra(CropImage.KEY_ASPECT_Y, widgetHeight)
-                .putExtra(CropImage.KEY_SCALE_UP_IF_NEEDED, true)
-                .putExtra(CropImage.KEY_SCALE, true)
-                .putExtra(CropImage.KEY_RETURN_DATA, true);
+                .putExtra(CropExtras.KEY_OUTPUT_X, widgetWidth)
+                .putExtra(CropExtras.KEY_OUTPUT_Y, widgetHeight)
+                .putExtra(CropExtras.KEY_ASPECT_X, widgetWidth)
+                .putExtra(CropExtras.KEY_ASPECT_Y, widgetHeight)
+                .putExtra(CropExtras.KEY_SCALE_UP_IF_NEEDED, true)
+                .putExtra(CropExtras.KEY_SCALE, true)
+                .putExtra(CropExtras.KEY_RETURN_DATA, true);
         startActivityForResult(request, REQUEST_CROP_IMAGE);
     }
 
diff --git a/src/com/android/gallery3d/ui/CropView.java b/src/com/android/gallery3d/ui/CropView.java
deleted file mode 100644 (file)
index a575557..0000000
+++ /dev/null
@@ -1,794 +0,0 @@
-/*
- * Copyright (C) 2010 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.ui;
-
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.PointF;
-import android.graphics.RectF;
-import android.media.FaceDetector;
-import android.os.Handler;
-import android.os.Message;
-import android.util.FloatMath;
-import android.view.MotionEvent;
-import android.view.animation.DecelerateInterpolator;
-import android.widget.Toast;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.anim.Animation;
-import com.android.gallery3d.app.AbstractGalleryActivity;
-import com.android.gallery3d.common.Utils;
-
-import java.util.ArrayList;
-
-/**
- * The activity can crop specific region of interest from an image.
- */
-public class CropView extends GLView {
-    @SuppressWarnings("unused")
-    private static final String TAG = "CropView";
-
-    private static final int FACE_PIXEL_COUNT = 120000; // around 400x300
-
-    private static final int COLOR_OUTLINE = 0xFF008AFF;
-    private static final int COLOR_FACE_OUTLINE = 0xFF000000;
-
-    private static final float OUTLINE_WIDTH = 3f;
-
-    private static final int SIZE_UNKNOWN = -1;
-    private static final int TOUCH_TOLERANCE = 30;
-
-    private static final float MIN_SELECTION_LENGTH = 16f;
-    public static final float UNSPECIFIED = -1f;
-
-    private static final int MAX_FACE_COUNT = 3;
-    private static final float FACE_EYE_RATIO = 2f;
-
-    private static final int ANIMATION_DURATION = 1250;
-
-    private static final int MOVE_LEFT = 1;
-    private static final int MOVE_TOP = 2;
-    private static final int MOVE_RIGHT = 4;
-    private static final int MOVE_BOTTOM = 8;
-    private static final int MOVE_BLOCK = 16;
-
-    private static final float MAX_SELECTION_RATIO = 0.8f;
-    private static final float MIN_SELECTION_RATIO = 0.4f;
-    private static final float SELECTION_RATIO = 0.60f;
-    private static final int ANIMATION_TRIGGER = 64;
-
-    private static final int MSG_UPDATE_FACES = 1;
-
-    private float mAspectRatio = UNSPECIFIED;
-    private float mSpotlightRatioX = 0;
-    private float mSpotlightRatioY = 0;
-
-    private Handler mMainHandler;
-
-    private FaceHighlightView mFaceDetectionView;
-    private HighlightRectangle mHighlightRectangle;
-    private TileImageView mImageView;
-    private AnimationController mAnimation = new AnimationController();
-
-    private int mImageWidth = SIZE_UNKNOWN;
-    private int mImageHeight = SIZE_UNKNOWN;
-
-    private AbstractGalleryActivity mActivity;
-
-    private GLPaint mPaint = new GLPaint();
-    private GLPaint mFacePaint = new GLPaint();
-
-    private int mImageRotation;
-
-    public CropView(AbstractGalleryActivity activity) {
-        mActivity = activity;
-        mImageView = new TileImageView(activity);
-        mFaceDetectionView = new FaceHighlightView();
-        mHighlightRectangle = new HighlightRectangle();
-
-        addComponent(mImageView);
-        addComponent(mFaceDetectionView);
-        addComponent(mHighlightRectangle);
-
-        mHighlightRectangle.setVisibility(GLView.INVISIBLE);
-
-        mPaint.setColor(COLOR_OUTLINE);
-        mPaint.setLineWidth(OUTLINE_WIDTH);
-
-        mFacePaint.setColor(COLOR_FACE_OUTLINE);
-        mFacePaint.setLineWidth(OUTLINE_WIDTH);
-
-        mMainHandler = new SynchronizedHandler(activity.getGLRoot()) {
-            @Override
-            public void handleMessage(Message message) {
-                Utils.assertTrue(message.what == MSG_UPDATE_FACES);
-                ((DetectFaceTask) message.obj).updateFaces();
-            }
-        };
-    }
-
-    public void setAspectRatio(float ratio) {
-        mAspectRatio = ratio;
-    }
-
-    public void setSpotlightRatio(float ratioX, float ratioY) {
-        mSpotlightRatioX = ratioX;
-        mSpotlightRatioY = ratioY;
-    }
-
-    @Override
-    public void onLayout(boolean changed, int l, int t, int r, int b) {
-        int width = r - l;
-        int height = b - t;
-
-        mFaceDetectionView.layout(0, 0, width, height);
-        mHighlightRectangle.layout(0, 0, width, height);
-        mImageView.layout(0, 0, width, height);
-        if (mImageHeight != SIZE_UNKNOWN) {
-            mAnimation.initialize();
-            if (mHighlightRectangle.getVisibility() == GLView.VISIBLE) {
-                mAnimation.parkNow(
-                        mHighlightRectangle.mHighlightRect);
-            }
-        }
-    }
-
-    private boolean setImageViewPosition(int centerX, int centerY, float scale) {
-        int inverseX = mImageWidth - centerX;
-        int inverseY = mImageHeight - centerY;
-        TileImageView t = mImageView;
-        int rotation = mImageRotation;
-        switch (rotation) {
-            case 0: return t.setPosition(centerX, centerY, scale, 0);
-            case 90: return t.setPosition(centerY, inverseX, scale, 90);
-            case 180: return t.setPosition(inverseX, inverseY, scale, 180);
-            case 270: return t.setPosition(inverseY, centerX, scale, 270);
-            default: throw new IllegalArgumentException(String.valueOf(rotation));
-        }
-    }
-
-    @Override
-    public void render(GLCanvas canvas) {
-        AnimationController a = mAnimation;
-        if (a.calculate(AnimationTime.get())) invalidate();
-        setImageViewPosition(a.getCenterX(), a.getCenterY(), a.getScale());
-        super.render(canvas);
-    }
-
-    @Override
-    public void renderBackground(GLCanvas canvas) {
-        canvas.clearBuffer();
-    }
-
-    public RectF getCropRectangle() {
-        if (mHighlightRectangle.getVisibility() == GLView.INVISIBLE) return null;
-        RectF rect = mHighlightRectangle.mHighlightRect;
-        RectF result = new RectF(rect.left * mImageWidth, rect.top * mImageHeight,
-                rect.right * mImageWidth, rect.bottom * mImageHeight);
-        return result;
-    }
-
-    public int getImageWidth() {
-        return mImageWidth;
-    }
-
-    public int getImageHeight() {
-        return mImageHeight;
-    }
-
-    private class FaceHighlightView extends GLView {
-        private static final int INDEX_NONE = -1;
-        private ArrayList<RectF> mFaces = new ArrayList<RectF>();
-        private RectF mRect = new RectF();
-        private int mPressedFaceIndex = INDEX_NONE;
-
-        public void addFace(RectF faceRect) {
-            mFaces.add(faceRect);
-            invalidate();
-        }
-
-        private void renderFace(GLCanvas canvas, RectF face, boolean pressed) {
-            if (pressed) {
-                canvas.enableStencil();
-                canvas.clearStencilBuffer();
-                canvas.updateStencil(true);
-                canvas.drawOnlyOutsideStencil(false);
-            }
-
-            RectF r = mAnimation.mapRect(face, mRect);
-            canvas.fillRect(r.left, r.top, r.width(), r.height(), Color.TRANSPARENT);
-            canvas.drawRect(r.left, r.top, r.width(), r.height(), mFacePaint);
-
-            if (pressed) {
-                canvas.updateStencil(false);
-                canvas.disableStencil();
-            }
-        }
-
-        @Override
-        protected void renderBackground(GLCanvas canvas) {
-            ArrayList<RectF> faces = mFaces;
-            for (int i = 0, n = faces.size(); i < n; ++i) {
-                renderFace(canvas, faces.get(i), i == mPressedFaceIndex);
-            }
-
-            if (mPressedFaceIndex != INDEX_NONE) {
-                canvas.enableStencil();
-                canvas.drawOnlyOutsideStencil(true);
-                canvas.fillRect(0, 0, getWidth(), getHeight(), 0x66000000);
-                canvas.disableStencil();
-            }
-        }
-
-        private void setPressedFace(int index) {
-            if (mPressedFaceIndex == index) return;
-            mPressedFaceIndex = index;
-            invalidate();
-        }
-
-        private int getFaceIndexByPosition(float x, float y) {
-            ArrayList<RectF> faces = mFaces;
-            for (int i = 0, n = faces.size(); i < n; ++i) {
-                RectF r = mAnimation.mapRect(faces.get(i), mRect);
-                if (r.contains(x, y)) return i;
-            }
-            return INDEX_NONE;
-        }
-
-        @Override
-        protected boolean onTouch(MotionEvent event) {
-            float x = event.getX();
-            float y = event.getY();
-            switch (event.getAction()) {
-                case MotionEvent.ACTION_DOWN:
-                case MotionEvent.ACTION_MOVE: {
-                    setPressedFace(getFaceIndexByPosition(x, y));
-                    break;
-                }
-                case MotionEvent.ACTION_CANCEL:
-                case MotionEvent.ACTION_UP: {
-                    int index = mPressedFaceIndex;
-                    setPressedFace(INDEX_NONE);
-                    if (index != INDEX_NONE) {
-                        mHighlightRectangle.setRectangle(mFaces.get(index));
-                        mHighlightRectangle.setVisibility(GLView.VISIBLE);
-                        setVisibility(GLView.INVISIBLE);
-                    }
-                }
-            }
-            return true;
-        }
-    }
-
-    private class AnimationController extends Animation {
-        private int mCurrentX;
-        private int mCurrentY;
-        private float mCurrentScale;
-        private int mStartX;
-        private int mStartY;
-        private float mStartScale;
-        private int mTargetX;
-        private int mTargetY;
-        private float mTargetScale;
-
-        public AnimationController() {
-            setDuration(ANIMATION_DURATION);
-            setInterpolator(new DecelerateInterpolator(4));
-        }
-
-        public void initialize() {
-            mCurrentX = mImageWidth / 2;
-            mCurrentY = mImageHeight / 2;
-            mCurrentScale = Math.min(2, Math.min(
-                    (float) getWidth() / mImageWidth,
-                    (float) getHeight() / mImageHeight));
-        }
-
-        public void startParkingAnimation(RectF highlight) {
-            RectF r = mAnimation.mapRect(highlight, new RectF());
-            int width = getWidth();
-            int height = getHeight();
-
-            float wr = r.width() / width;
-            float hr = r.height() / height;
-            final int d = ANIMATION_TRIGGER;
-            if (wr >= MIN_SELECTION_RATIO && wr < MAX_SELECTION_RATIO
-                    && hr >= MIN_SELECTION_RATIO && hr < MAX_SELECTION_RATIO
-                    && r.left >= d && r.right < width - d
-                    && r.top >= d && r.bottom < height - d) return;
-
-            mStartX = mCurrentX;
-            mStartY = mCurrentY;
-            mStartScale = mCurrentScale;
-            calculateTarget(highlight);
-            start();
-        }
-
-        public void parkNow(RectF highlight) {
-            calculateTarget(highlight);
-            forceStop();
-            mStartX = mCurrentX = mTargetX;
-            mStartY = mCurrentY = mTargetY;
-            mStartScale = mCurrentScale = mTargetScale;
-        }
-
-        public void inverseMapPoint(PointF point) {
-            float s = mCurrentScale;
-            point.x = Utils.clamp(((point.x - getWidth() * 0.5f) / s
-                    + mCurrentX) / mImageWidth, 0, 1);
-            point.y = Utils.clamp(((point.y - getHeight() * 0.5f) / s
-                    + mCurrentY) / mImageHeight, 0, 1);
-        }
-
-        public RectF mapRect(RectF input, RectF output) {
-            float offsetX = getWidth() * 0.5f;
-            float offsetY = getHeight() * 0.5f;
-            int x = mCurrentX;
-            int y = mCurrentY;
-            float s = mCurrentScale;
-            output.set(
-                    offsetX + (input.left * mImageWidth - x) * s,
-                    offsetY + (input.top * mImageHeight - y) * s,
-                    offsetX + (input.right * mImageWidth - x) * s,
-                    offsetY + (input.bottom * mImageHeight - y) * s);
-            return output;
-        }
-
-        @Override
-        protected void onCalculate(float progress) {
-            mCurrentX = Math.round(mStartX + (mTargetX - mStartX) * progress);
-            mCurrentY = Math.round(mStartY + (mTargetY - mStartY) * progress);
-            mCurrentScale = mStartScale + (mTargetScale - mStartScale) * progress;
-
-            if (mCurrentX == mTargetX && mCurrentY == mTargetY
-                    && mCurrentScale == mTargetScale) forceStop();
-        }
-
-        public int getCenterX() {
-            return mCurrentX;
-        }
-
-        public int getCenterY() {
-            return mCurrentY;
-        }
-
-        public float getScale() {
-            return mCurrentScale;
-        }
-
-        private void calculateTarget(RectF highlight) {
-            float width = getWidth();
-            float height = getHeight();
-
-            if (mImageWidth != SIZE_UNKNOWN) {
-                float minScale = Math.min(width / mImageWidth, height / mImageHeight);
-                float scale = Utils.clamp(SELECTION_RATIO * Math.min(
-                        width / (highlight.width() * mImageWidth),
-                        height / (highlight.height() * mImageHeight)), minScale, 2f);
-                int centerX = Math.round(
-                        mImageWidth * (highlight.left + highlight.right) * 0.5f);
-                int centerY = Math.round(
-                        mImageHeight * (highlight.top + highlight.bottom) * 0.5f);
-
-                if (Math.round(mImageWidth * scale) > width) {
-                    int limitX = Math.round(width * 0.5f / scale);
-                    centerX = Math.round(
-                            (highlight.left + highlight.right) * mImageWidth / 2);
-                    centerX = Utils.clamp(centerX, limitX, mImageWidth - limitX);
-                } else {
-                    centerX = mImageWidth / 2;
-                }
-                if (Math.round(mImageHeight * scale) > height) {
-                    int limitY = Math.round(height * 0.5f / scale);
-                    centerY = Math.round(
-                            (highlight.top + highlight.bottom) * mImageHeight / 2);
-                    centerY = Utils.clamp(centerY, limitY, mImageHeight - limitY);
-                } else {
-                    centerY = mImageHeight / 2;
-                }
-                mTargetX = centerX;
-                mTargetY = centerY;
-                mTargetScale = scale;
-            }
-        }
-
-    }
-
-    private class HighlightRectangle extends GLView {
-        private RectF mHighlightRect = new RectF(0.25f, 0.25f, 0.75f, 0.75f);
-        private RectF mTempRect = new RectF();
-        private PointF mTempPoint = new PointF();
-
-        private ResourceTexture mArrow;
-
-        private int mMovingEdges = 0;
-        private float mReferenceX;
-        private float mReferenceY;
-
-        public HighlightRectangle() {
-            mArrow = new ResourceTexture(mActivity.getAndroidContext(),
-                    R.drawable.camera_crop_holo);
-        }
-
-        public void setInitRectangle() {
-            float targetRatio = mAspectRatio == UNSPECIFIED
-                    ? 1f
-                    : mAspectRatio * mImageHeight / mImageWidth;
-            float w = SELECTION_RATIO / 2f;
-            float h = SELECTION_RATIO / 2f;
-            if (targetRatio > 1) {
-                h = w / targetRatio;
-            } else {
-                w = h * targetRatio;
-            }
-            mHighlightRect.set(0.5f - w, 0.5f - h, 0.5f + w, 0.5f + h);
-        }
-
-        public void setRectangle(RectF faceRect) {
-            mHighlightRect.set(faceRect);
-            mAnimation.startParkingAnimation(faceRect);
-            invalidate();
-        }
-
-        private void moveEdges(MotionEvent event) {
-            float scale = mAnimation.getScale();
-            float dx = (event.getX() - mReferenceX) / scale / mImageWidth;
-            float dy = (event.getY() - mReferenceY) / scale / mImageHeight;
-            mReferenceX = event.getX();
-            mReferenceY = event.getY();
-            RectF r = mHighlightRect;
-
-            if ((mMovingEdges & MOVE_BLOCK) != 0) {
-                dx = Utils.clamp(dx, -r.left,  1 - r.right);
-                dy = Utils.clamp(dy, -r.top , 1 - r.bottom);
-                r.top += dy;
-                r.bottom += dy;
-                r.left += dx;
-                r.right += dx;
-            } else {
-                PointF point = mTempPoint;
-                point.set(mReferenceX, mReferenceY);
-                mAnimation.inverseMapPoint(point);
-                float left = r.left + MIN_SELECTION_LENGTH / mImageWidth;
-                float right = r.right - MIN_SELECTION_LENGTH / mImageWidth;
-                float top = r.top + MIN_SELECTION_LENGTH / mImageHeight;
-                float bottom = r.bottom - MIN_SELECTION_LENGTH / mImageHeight;
-                if ((mMovingEdges & MOVE_RIGHT) != 0) {
-                    r.right = Utils.clamp(point.x, left, 1f);
-                }
-                if ((mMovingEdges & MOVE_LEFT) != 0) {
-                    r.left = Utils.clamp(point.x, 0, right);
-                }
-                if ((mMovingEdges & MOVE_TOP) != 0) {
-                    r.top = Utils.clamp(point.y, 0, bottom);
-                }
-                if ((mMovingEdges & MOVE_BOTTOM) != 0) {
-                    r.bottom = Utils.clamp(point.y, top, 1f);
-                }
-                if (mAspectRatio != UNSPECIFIED) {
-                    float targetRatio = mAspectRatio * mImageHeight / mImageWidth;
-                    if (r.width() / r.height() > targetRatio) {
-                        float height = r.width() / targetRatio;
-                        if ((mMovingEdges & MOVE_BOTTOM) != 0) {
-                            r.bottom = Utils.clamp(r.top + height, top, 1f);
-                        } else {
-                            r.top = Utils.clamp(r.bottom - height, 0, bottom);
-                        }
-                    } else {
-                        float width = r.height() * targetRatio;
-                        if ((mMovingEdges & MOVE_LEFT) != 0) {
-                            r.left = Utils.clamp(r.right - width, 0, right);
-                        } else {
-                            r.right = Utils.clamp(r.left + width, left, 1f);
-                        }
-                    }
-                    if (r.width() / r.height() > targetRatio) {
-                        float width = r.height() * targetRatio;
-                        if ((mMovingEdges & MOVE_LEFT) != 0) {
-                            r.left = Utils.clamp(r.right - width, 0, right);
-                        } else {
-                            r.right = Utils.clamp(r.left + width, left, 1f);
-                        }
-                    } else {
-                        float height = r.width() / targetRatio;
-                        if ((mMovingEdges & MOVE_BOTTOM) != 0) {
-                            r.bottom = Utils.clamp(r.top + height, top, 1f);
-                        } else {
-                            r.top = Utils.clamp(r.bottom - height, 0, bottom);
-                        }
-                    }
-                }
-            }
-            invalidate();
-        }
-
-        private void setMovingEdges(MotionEvent event) {
-            RectF r = mAnimation.mapRect(mHighlightRect, mTempRect);
-            float x = event.getX();
-            float y = event.getY();
-
-            if (x > r.left + TOUCH_TOLERANCE && x < r.right - TOUCH_TOLERANCE
-                    && y > r.top + TOUCH_TOLERANCE && y < r.bottom - TOUCH_TOLERANCE) {
-                mMovingEdges = MOVE_BLOCK;
-                return;
-            }
-
-            boolean inVerticalRange = (r.top - TOUCH_TOLERANCE) <= y
-                    && y <= (r.bottom + TOUCH_TOLERANCE);
-            boolean inHorizontalRange = (r.left - TOUCH_TOLERANCE) <= x
-                    && x <= (r.right + TOUCH_TOLERANCE);
-
-            if (inVerticalRange) {
-                boolean left = Math.abs(x - r.left) <= TOUCH_TOLERANCE;
-                boolean right = Math.abs(x - r.right) <= TOUCH_TOLERANCE;
-                if (left && right) {
-                    left = Math.abs(x - r.left) < Math.abs(x - r.right);
-                    right = !left;
-                }
-                if (left) mMovingEdges |= MOVE_LEFT;
-                if (right) mMovingEdges |= MOVE_RIGHT;
-                if (mAspectRatio != UNSPECIFIED && inHorizontalRange) {
-                    mMovingEdges |= (y >
-                            (r.top + r.bottom) / 2) ? MOVE_BOTTOM : MOVE_TOP;
-                }
-            }
-            if (inHorizontalRange) {
-                boolean top = Math.abs(y - r.top) <= TOUCH_TOLERANCE;
-                boolean bottom = Math.abs(y - r.bottom) <= TOUCH_TOLERANCE;
-                if (top && bottom) {
-                    top = Math.abs(y - r.top) < Math.abs(y - r.bottom);
-                    bottom = !top;
-                }
-                if (top) mMovingEdges |= MOVE_TOP;
-                if (bottom) mMovingEdges |= MOVE_BOTTOM;
-                if (mAspectRatio != UNSPECIFIED && inVerticalRange) {
-                    mMovingEdges |= (x >
-                            (r.left + r.right) / 2) ? MOVE_RIGHT : MOVE_LEFT;
-                }
-            }
-        }
-
-        @Override
-        protected boolean onTouch(MotionEvent event) {
-            switch (event.getAction()) {
-                case MotionEvent.ACTION_DOWN: {
-                    mReferenceX = event.getX();
-                    mReferenceY = event.getY();
-                    setMovingEdges(event);
-                    invalidate();
-                    return true;
-                }
-                case MotionEvent.ACTION_MOVE:
-                    moveEdges(event);
-                    break;
-                case MotionEvent.ACTION_CANCEL:
-                case MotionEvent.ACTION_UP: {
-                    mMovingEdges = 0;
-                    mAnimation.startParkingAnimation(mHighlightRect);
-                    invalidate();
-                    return true;
-                }
-            }
-            return true;
-        }
-
-        @Override
-        protected void renderBackground(GLCanvas canvas) {
-            RectF r = mAnimation.mapRect(mHighlightRect, mTempRect);
-            drawHighlightRectangle(canvas, r);
-
-            float centerY = (r.top + r.bottom) / 2;
-            float centerX = (r.left + r.right) / 2;
-            boolean notMoving = mMovingEdges == 0;
-            if ((mMovingEdges & MOVE_RIGHT) != 0 || notMoving) {
-                mArrow.draw(canvas,
-                        Math.round(r.right - mArrow.getWidth() / 2),
-                        Math.round(centerY - mArrow.getHeight() / 2));
-            }
-            if ((mMovingEdges & MOVE_LEFT) != 0 || notMoving) {
-                mArrow.draw(canvas,
-                        Math.round(r.left - mArrow.getWidth() / 2),
-                        Math.round(centerY - mArrow.getHeight() / 2));
-            }
-            if ((mMovingEdges & MOVE_TOP) != 0 || notMoving) {
-                mArrow.draw(canvas,
-                        Math.round(centerX - mArrow.getWidth() / 2),
-                        Math.round(r.top - mArrow.getHeight() / 2));
-            }
-            if ((mMovingEdges & MOVE_BOTTOM) != 0 || notMoving) {
-                mArrow.draw(canvas,
-                        Math.round(centerX - mArrow.getWidth() / 2),
-                        Math.round(r.bottom - mArrow.getHeight() / 2));
-            }
-        }
-
-        private void drawHighlightRectangle(GLCanvas canvas, RectF r) {
-
-            canvas.enableStencil();
-            canvas.clearStencilBuffer();
-            canvas.updateStencil(true);
-            canvas.drawOnlyOutsideStencil(false);
-
-            if (mSpotlightRatioX == 0 || mSpotlightRatioY == 0) {
-                canvas.fillRect(r.left, r.top, r.width(), r.height(), Color.TRANSPARENT);
-                canvas.drawRect(r.left, r.top, r.width(), r.height(), mPaint);
-                canvas.drawOnlyOutsideStencil(true);
-            } else {
-                float sx = r.width() * mSpotlightRatioX;
-                float sy = r.height() * mSpotlightRatioY;
-                float cx = r.centerX();
-                float cy = r.centerY();
-
-                canvas.fillRect(cx - sx / 2, cy - sy / 2, sx, sy, Color.TRANSPARENT);
-                canvas.drawRect(cx - sx / 2, cy - sy / 2, sx, sy, mPaint);
-                canvas.drawRect(r.left, r.top, r.width(), r.height(), mPaint);
-
-                canvas.drawOnlyOutsideStencil(true);
-
-                canvas.drawRect(cx - sy / 2, cy - sx / 2, sy, sx, mPaint);
-                canvas.fillRect(cx - sy / 2, cy - sx / 2, sy, sx, Color.TRANSPARENT);
-                canvas.fillRect(r.left, r.top, r.width(), r.height(), 0x80000000);
-            }
-
-            canvas.updateStencil(false);
-            canvas.fillRect(0, 0, getWidth(), getHeight(), 0xA0000000);
-
-            canvas.disableStencil();
-        }
-    }
-
-    private class DetectFaceTask extends Thread {
-        private final FaceDetector.Face[] mFaces = new FaceDetector.Face[MAX_FACE_COUNT];
-        private final Bitmap mFaceBitmap;
-        private int mFaceCount;
-
-        public DetectFaceTask(Bitmap bitmap) {
-            mFaceBitmap = bitmap;
-            setName("face-detect");
-        }
-
-        @Override
-        public void run() {
-            Bitmap bitmap = mFaceBitmap;
-            FaceDetector detector = new FaceDetector(
-                    bitmap.getWidth(), bitmap.getHeight(), MAX_FACE_COUNT);
-            mFaceCount = detector.findFaces(bitmap, mFaces);
-            mMainHandler.sendMessage(
-                    mMainHandler.obtainMessage(MSG_UPDATE_FACES, this));
-        }
-
-        private RectF getFaceRect(FaceDetector.Face face) {
-            PointF point = new PointF();
-            face.getMidPoint(point);
-
-            int width = mFaceBitmap.getWidth();
-            int height = mFaceBitmap.getHeight();
-            float rx = face.eyesDistance() * FACE_EYE_RATIO;
-            float ry = rx;
-            float aspect = mAspectRatio;
-            if (aspect != UNSPECIFIED) {
-                if (aspect > 1) {
-                    rx = ry * aspect;
-                } else {
-                    ry = rx / aspect;
-                }
-            }
-
-            RectF r = new RectF(
-                    point.x - rx, point.y - ry, point.x + rx, point.y + ry);
-            r.intersect(0, 0, width, height);
-
-            if (aspect != UNSPECIFIED) {
-                if (r.width() / r.height() > aspect) {
-                    float w = r.height() * aspect;
-                    r.left = (r.left + r.right - w) * 0.5f;
-                    r.right = r.left + w;
-                } else {
-                    float h = r.width() / aspect;
-                    r.top =  (r.top + r.bottom - h) * 0.5f;
-                    r.bottom = r.top + h;
-                }
-            }
-
-            r.left /= width;
-            r.right /= width;
-            r.top /= height;
-            r.bottom /= height;
-            return r;
-        }
-
-        public void updateFaces() {
-            if (mFaceCount > 1) {
-                for (int i = 0, n = mFaceCount; i < n; ++i) {
-                    mFaceDetectionView.addFace(getFaceRect(mFaces[i]));
-                }
-                mFaceDetectionView.setVisibility(GLView.VISIBLE);
-                Toast.makeText(mActivity.getAndroidContext(),
-                        R.string.multiface_crop_help, Toast.LENGTH_SHORT).show();
-            } else if (mFaceCount == 1) {
-                mFaceDetectionView.setVisibility(GLView.INVISIBLE);
-                mHighlightRectangle.setRectangle(getFaceRect(mFaces[0]));
-                mHighlightRectangle.setVisibility(GLView.VISIBLE);
-            } else /*mFaceCount == 0*/ {
-                mHighlightRectangle.setInitRectangle();
-                mHighlightRectangle.setVisibility(GLView.VISIBLE);
-            }
-        }
-    }
-
-    public void setDataModel(TileImageView.Model dataModel, int rotation) {
-        if (((rotation / 90) & 0x01) != 0) {
-            mImageWidth = dataModel.getImageHeight();
-            mImageHeight = dataModel.getImageWidth();
-        } else {
-            mImageWidth = dataModel.getImageWidth();
-            mImageHeight = dataModel.getImageHeight();
-        }
-
-        mImageRotation = rotation;
-
-        mImageView.setModel(dataModel);
-        mAnimation.initialize();
-    }
-
-    public void detectFaces(Bitmap bitmap) {
-        int rotation = mImageRotation;
-        int width = bitmap.getWidth();
-        int height = bitmap.getHeight();
-        float scale = FloatMath.sqrt((float) FACE_PIXEL_COUNT / (width * height));
-
-        // faceBitmap is a correctly rotated bitmap, as viewed by a user.
-        Bitmap faceBitmap;
-        if (((rotation / 90) & 1) == 0) {
-            int w = (Math.round(width * scale) & ~1); // must be even
-            int h = Math.round(height * scale);
-            faceBitmap = Bitmap.createBitmap(w, h, Config.RGB_565);
-            Canvas canvas = new Canvas(faceBitmap);
-            canvas.rotate(rotation, w / 2, h / 2);
-            canvas.scale((float) w / width, (float) h / height);
-            canvas.drawBitmap(bitmap, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG));
-        } else {
-            int w = (Math.round(height * scale) & ~1); // must be even
-            int h = Math.round(width * scale);
-            faceBitmap = Bitmap.createBitmap(w, h, Config.RGB_565);
-            Canvas canvas = new Canvas(faceBitmap);
-            canvas.translate(w / 2, h / 2);
-            canvas.rotate(rotation);
-            canvas.translate(-h / 2, -w / 2);
-            canvas.scale((float) w / height, (float) h / width);
-            canvas.drawBitmap(bitmap, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG));
-        }
-        new DetectFaceTask(faceBitmap).start();
-    }
-
-    public void initializeHighlightRectangle() {
-        mHighlightRectangle.setInitRectangle();
-        mHighlightRectangle.setVisibility(GLView.VISIBLE);
-    }
-
-    public void resume() {
-        mImageView.prepareTextures();
-    }
-
-    public void pause() {
-        mImageView.freeTextures();
-    }
-}
-
index 847ec89..a9eeaf8 100644 (file)
@@ -31,7 +31,6 @@ import com.actionbarsherlock.view.Menu;
 import com.actionbarsherlock.view.MenuItem;
 import com.android.gallery3d.R;
 import com.android.gallery3d.app.AbstractGalleryActivity;
-import com.android.gallery3d.app.CropImage;
 import com.android.gallery3d.common.ApiHelper;
 import com.android.gallery3d.common.Utils;
 import com.android.gallery3d.data.DataManager;