OSDN Git Service

Tweak the peek animation image size.
authorAngus Kong <shkong@google.com>
Fri, 21 Feb 2014 00:56:37 +0000 (16:56 -0800)
committerAngus Kong <shkong@google.com>
Fri, 21 Feb 2014 02:36:46 +0000 (18:36 -0800)
bug:12451161
Change-Id: Ie5a8a2911ed4b5ce831331ca7e7600d6d13659b7

src/com/android/camera/CameraActivity.java
src/com/android/camera/data/InProgressDataWrapper.java
src/com/android/camera/data/LocalDataUtil.java
src/com/android/camera/data/LocalMediaData.java
src/com/android/camera/data/RotationTask.java
src/com/android/camera/data/SimpleViewData.java
src/com/android/camera/filmstrip/ImageData.java
src/com/android/camera/util/CameraUtil.java
src/com/android/camera/widget/FilmstripView.java
src/com/android/camera/widget/PeekView.java

index fdbfe86..02096ad 100644 (file)
@@ -34,6 +34,7 @@ import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.Matrix;
+import android.graphics.Point;
 import android.graphics.SurfaceTexture;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
@@ -951,7 +952,7 @@ public class CameraActivity extends Activity
             return;
         }
 
-        mPeekAnimationHandler.startAnimationJob(data, new Callback<Bitmap>() {
+        mPeekAnimationHandler.startDecodingJob(data, new Callback<Bitmap>() {
             @Override
             public void onCallback(Bitmap result) {
                 mCameraAppUI.startPeekAnimation(result, true);
@@ -2026,9 +2027,8 @@ public class CameraActivity extends Activity
          * @param callback {@link com.android.camera.util.Callback} after the
          *                 decoding is done.
          */
-        public void startAnimationJob(final LocalData data,
-                final com.android.camera.util.Callback<Bitmap>
-                callback) {
+        public void startDecodingJob(final LocalData data,
+                final com.android.camera.util.Callback<Bitmap> callback) {
             PeekAnimationHandler.this.obtainMessage(0 /** dummy integer **/,
                     new DataAndCallback(data, callback)).sendToTarget();
         }
@@ -2053,10 +2053,18 @@ public class CameraActivity extends Activity
                         Log.e(TAG, "File not found:" + data.getPath());
                         return;
                     }
+                    Point dim = CameraUtil.resizeToFill(data.getWidth(), data.getHeight(),
+                            data.getRotation(), mAboveFilmstripControlLayout.getWidth(),
+                            mAboveFilmstripControlLayout.getMeasuredHeight());
+                    if (data.getRotation() % 180 != 0) {
+                        int dummy = dim.x;
+                        dim.x = dim.y;
+                        dim.y = dummy;
+                    }
                     bitmap = LocalDataUtil
                             .loadImageThumbnailFromStream(stream, data.getWidth(), data.getHeight(),
-                                    data.getWidth() / 4, data.getHeight() / 4,
-                                    data.getOrientation(), MAX_PEEK_BITMAP_PIXELS);
+                                    (int) (dim.x * 0.7f), (int) (dim.y * 0.7),
+                                    data.getRotation(), MAX_PEEK_BITMAP_PIXELS);
                     break;
 
                 case LocalData.LOCAL_VIDEO:
index e076d80..eb48c73 100644 (file)
@@ -172,8 +172,8 @@ public class InProgressDataWrapper implements LocalData {
     }
 
     @Override
-    public int getOrientation() {
-        return mLocalData.getOrientation();
+    public int getRotation() {
+        return mLocalData.getRotation();
     }
 
     @Override
index 1c7f883..c51dc11 100644 (file)
@@ -100,6 +100,12 @@ public class LocalDataUtil {
         /** 32K buffer. */
         byte[] decodeBuffer = new byte[32 * 1024];
 
+        if (orientation % 180 != 0) {
+            int dummy = imageHeight;
+            imageHeight = imageWidth;
+            imageWidth = dummy;
+        }
+
         // Generate Bitmap of maximum size that fits into widthBound x heightBound.
         // Algorithm: start with full size and step down in powers of 2.
         int targetWidth = imageWidth;
index 83f2614..c8ef3c2 100644 (file)
@@ -127,7 +127,7 @@ public abstract class LocalMediaData implements LocalData {
     }
 
     @Override
-    public int getOrientation() {
+    public int getRotation() {
         return 0;
     }
 
@@ -381,7 +381,7 @@ public abstract class LocalMediaData implements LocalData {
         }
 
         @Override
-        public int getOrientation() {
+        public int getRotation() {
             return mOrientation;
         }
 
index d94113c..c872f74 100644 (file)
@@ -82,7 +82,7 @@ public class RotationTask extends AsyncTask<LocalData, Void, LocalData> {
         }
 
         PhotoData imageData = (PhotoData) data;
-        int originRotation = imageData.getOrientation();
+        int originRotation = imageData.getRotation();
         int finalRotationDegrees;
         if (mClockwise) {
             finalRotationDegrees = (originRotation + 90) % 360;
index 1141323..705fe36 100644 (file)
@@ -77,7 +77,7 @@ public class SimpleViewData implements LocalData {
     }
 
     @Override
-    public int getOrientation() {
+    public int getRotation() {
         return 0;
     }
 
index 52f8ffa..6a51d3e 100644 (file)
@@ -73,10 +73,10 @@ public interface ImageData {
     public int getHeight();
 
     /**
-     * Returns the orientation of the image in degrees. The valid values are
-     * 0, 90, 180, and 270.
+     * Returns the rotation of the image in degrees clockwise. The valid values
+     * are 0, 90, 180, and 270.
      */
-    public int getOrientation();
+    public int getRotation();
 
     /** Returns the image data type. The current valid values are
      * {@code VIEW_TYPE_*}.
index 416f828..1207519 100644 (file)
@@ -55,6 +55,7 @@ import android.widget.Toast;
 
 import com.android.camera.CameraActivity;
 import com.android.camera.CameraDisabledException;
+import com.android.camera.filmstrip.ImageData;
 import com.android.camera2.R;
 
 import java.io.Closeable;
@@ -1002,6 +1003,47 @@ public class CameraUtil {
         }
     }
 
+    /**
+     * Calculates a new dimension to fill the bound with the original aspect
+     * ratio preserved.
+     *
+     * @param imageWidth The original width.
+     * @param imageHeight The original height.
+     * @param imageRotation The clockwise rotation in degrees of the image
+     *                      which the original dimension comes from.
+     * @param boundWidth The width of the bound.
+     * @param boundHeight The height of the bound.
+     *
+     * @returns The final width/height stored in Point.x/Point.y to fill the
+     * bounds and preserve image aspect ratio.
+     */
+    public static Point resizeToFill(int imageWidth, int imageHeight, int imageRotation,
+            int boundWidth, int boundHeight) {
+        if (imageRotation % 180 != 0) {
+            // Swap width and height.
+            int savedWidth = imageWidth;
+            imageWidth = imageHeight;
+            imageHeight = savedWidth;
+        }
+        if (imageWidth == ImageData.SIZE_FULL
+                || imageHeight == ImageData.SIZE_FULL) {
+            imageWidth = boundWidth;
+            imageHeight = boundHeight;
+        }
+
+        Point p = new Point();
+        p.x = boundWidth;
+        p.y = boundHeight;
+
+        if (imageWidth * boundHeight > boundWidth * imageHeight) {
+            p.y = imageHeight * p.x / imageWidth;
+        } else {
+            p.x = imageWidth * p.y / imageHeight;
+        }
+
+        return p;
+    }
+
     private static class ImageFileNamer {
         private final SimpleDateFormat mFormat;
 
index 5923b7c..97a175f 100644 (file)
@@ -22,6 +22,7 @@ import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Canvas;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.net.Uri;
@@ -41,6 +42,7 @@ import com.android.camera.filmstrip.FilmstripController;
 import com.android.camera.filmstrip.ImageData;
 import com.android.camera.ui.FilmstripGestureRecognizer;
 import com.android.camera.ui.ZoomView;
+import com.android.camera.util.CameraUtil;
 import com.android.camera2.R;
 
 import java.util.Arrays;
@@ -606,35 +608,6 @@ public class FilmstripView extends ViewGroup {
         return false;
     }
 
-    /** Returns [width, height] preserving image aspect ratio. */
-    private int[] calculateChildDimension(
-            int imageWidth, int imageHeight, int imageOrientation,
-            int boundWidth, int boundHeight) {
-        if (imageOrientation == 90 || imageOrientation == 270) {
-            // Swap width and height.
-            int savedWidth = imageWidth;
-            imageWidth = imageHeight;
-            imageHeight = savedWidth;
-        }
-        if (imageWidth == ImageData.SIZE_FULL
-                || imageHeight == ImageData.SIZE_FULL) {
-            imageWidth = boundWidth;
-            imageHeight = boundHeight;
-        }
-
-        int[] ret = new int[2];
-        ret[0] = boundWidth;
-        ret[1] = boundHeight;
-
-        if (imageWidth * ret[1] > ret[0] * imageHeight) {
-            ret[1] = imageHeight * ret[0] / imageWidth;
-        } else {
-            ret[0] = imageWidth * ret[1] / imageHeight;
-        }
-
-        return ret;
-    }
-
     private void measureViewItem(ViewItem item, int boundWidth, int boundHeight) {
         int id = item.getId();
         ImageData imageData = mDataAdapter.getImageData(id);
@@ -643,12 +616,11 @@ public class FilmstripView extends ViewGroup {
             return;
         }
 
-        int[] dim = calculateChildDimension(imageData.getWidth(),
-                imageData.getHeight(),
-                imageData.getOrientation(), boundWidth, boundHeight);
+        Point dim = CameraUtil.resizeToFill(imageData.getWidth(), imageData.getHeight(),
+                imageData.getRotation(), boundWidth, boundHeight);
 
-        item.measure(MeasureSpec.makeMeasureSpec(dim[0], MeasureSpec.EXACTLY),
-                MeasureSpec.makeMeasureSpec(dim[1], MeasureSpec.EXACTLY));
+        item.measure(MeasureSpec.makeMeasureSpec(dim.x, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(dim.y, MeasureSpec.EXACTLY));
     }
 
     @Override
@@ -1359,10 +1331,10 @@ public class FilmstripView extends ViewGroup {
         }
 
         final ImageData data = mDataAdapter.getImageData(dataID);
-        int[] dim = calculateChildDimension(
-                data.getWidth(), data.getHeight(), data.getOrientation(),
-                getMeasuredWidth(), getMeasuredHeight());
-        final int offsetX = dim[0] + mViewGapInPixel;
+        Point dim = CameraUtil
+                .resizeToFill(data.getWidth(), data.getHeight(), data.getRotation(),
+                        getMeasuredWidth(), getMeasuredHeight());
+        final int offsetX = dim.x + mViewGapInPixel;
         ViewItem viewItem = buildItemFromData(dataID);
 
         if (insertedItemId >= mCurrentItem) {
@@ -1559,10 +1531,9 @@ public class FilmstripView extends ViewGroup {
             if (!mIsUserScrolling && !mController.isScrolling()) {
                 // If there is no scrolling at all, adjust mCenterX to place
                 // the current item at the center.
-                int[] dim = calculateChildDimension(
-                        data.getWidth(), data.getHeight(), data.getOrientation(),
-                        getMeasuredWidth(), getMeasuredHeight());
-                mCenterX = curr.getLeftPosition() + dim[0] / 2;
+                Point dim = CameraUtil.resizeToFill(data.getWidth(), data.getHeight(),
+                        data.getRotation(), getMeasuredWidth(), getMeasuredHeight());
+                mCenterX = curr.getLeftPosition() + dim.x / 2;
             }
         }
 
@@ -2210,8 +2181,8 @@ public class FilmstripView extends ViewGroup {
                 return FULL_SCREEN_SCALE;
             }
             float imageWidth = imageData.getWidth();
-            if (imageData.getOrientation() == 90
-                    || imageData.getOrientation() == 270) {
+            if (imageData.getRotation() == 90
+                    || imageData.getRotation() == 270) {
                 imageWidth = imageData.getHeight();
             }
             float scale = imageWidth / curr.getWidth();
@@ -2241,7 +2212,7 @@ public class FilmstripView extends ViewGroup {
             if (uri == null || uri == Uri.EMPTY) {
                 return;
             }
-            int orientation = imageData.getOrientation();
+            int orientation = imageData.getRotation();
             mZoomView.loadBitmap(uri, orientation, viewRect);
         }
 
index 37ded4c..0357a23 100644 (file)
@@ -21,28 +21,36 @@ import android.animation.AnimatorSet;
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Bitmap;
+import android.graphics.Canvas;
 import android.graphics.Point;
+import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
 import android.widget.ImageView;
 
+import com.android.camera.util.CameraUtil;
+
 /**
  * An ImageView which has the built-in peek animation support.
  */
 public class PeekView extends ImageView {
 
     private static final float ROTATE_ANGLE = -15f;
-    private static final long PEEK_IN_DURATION_MS = 300;
-    private static final long PEEK_STAY_DURATION_MS = 200;
-    private static final long PEEK_OUT_DURATION_MS = 300;
+    private static final long PEEK_IN_DURATION_MS = 200;
+    private static final long PEEK_STAY_DURATION_MS = 100;
+    private static final long PEEK_OUT_DURATION_MS = 200;
+    private static final float FILMSTRIP_SCALE = 0.7f;
 
     private AnimatorSet mPeekAnimator;
     private float mPeekRotateAngle;
     private Point mRotationPivot;
     private float mRotateScale;
     private boolean mAnimationCanceled;
+    private Drawable mImageDrawable;
+    private Rect mDrawableBound;
 
     public PeekView(Context context) {
         super(context);
@@ -61,12 +69,40 @@ public class PeekView extends ImageView {
 
     private void init() {
         mRotationPivot = new Point();
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+    }
+
+    @Override
+    protected void onDraw(Canvas c) {
+        super.onDraw(c);
+        if (mImageDrawable == null) {
+            return;
+        }
+        c.save();
+        c.rotate(mPeekRotateAngle, mRotationPivot.x, mRotationPivot.y);
+        mImageDrawable.setBounds(mDrawableBound);
+        mImageDrawable.draw(c);
+        c.restore();
+    }
+
+    /**
+     * Starts the peek animation.
+     *
+     * @param bitmap The bitmap for the animation.
+     * @param strong {@code true} if the animation is the strong version which
+     *               shows more portion of the bitmap.
+     */
+    public void startPeekAnimation(final Bitmap bitmap, boolean strong) {
         ValueAnimator.AnimatorUpdateListener updateListener =
                 new ValueAnimator.AnimatorUpdateListener() {
                     @Override
                     public void onAnimationUpdate(ValueAnimator valueAnimator) {
                         mPeekRotateAngle = mRotateScale * (Float) valueAnimator.getAnimatedValue();
-                        drawPeekAnimation();
+                        invalidate();
                     }
                 };
         ValueAnimator peekAnimateIn = ValueAnimator.ofFloat(0f, ROTATE_ANGLE);
@@ -106,25 +142,16 @@ public class PeekView extends ImageView {
 
             }
         });
-    }
 
-    @Override
-    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        setTranslationX(getMeasuredWidth());
-    }
-
-    /**
-     * Starts the peek animation.
-     *
-     * @param bitmap The bitmap for the animation.
-     * @param strong {@code true} if the animation is the strong version which
-     *               shows more portion of the bitmap.
-     */
-    public void startPeekAnimation(final Bitmap bitmap, boolean strong) {
         mRotateScale = (strong ? 1.0f : 0.5f);
-        setImageDrawable(new BitmapDrawable(getResources(), bitmap));
-        mRotationPivot.set(0, getHeight());
+        mImageDrawable = new BitmapDrawable(getResources(), bitmap);
+        Point drawDim = CameraUtil.resizeToFill(mImageDrawable.getIntrinsicWidth(),
+                mImageDrawable.getIntrinsicHeight(), 0, (int) (getWidth() * FILMSTRIP_SCALE),
+                (int) (getHeight() * FILMSTRIP_SCALE));
+        int x = getMeasuredWidth();
+        int y = (getMeasuredHeight() - drawDim.y) / 2;
+        mDrawableBound = new Rect(x, y, x + drawDim.x, y + drawDim.y);
+        mRotationPivot.set(x, (int) (y + drawDim.y * 1.1));
         mPeekAnimator.start();
     }
 
@@ -157,18 +184,8 @@ public class PeekView extends ImageView {
         }
     }
 
-    private void drawPeekAnimation() {
-        if (mPeekAnimator.isRunning()) {
-            setTranslationX(getMeasuredWidth());
-            setRotation(mPeekRotateAngle);
-            setPivotX(mRotationPivot.x);
-            setPivotY(mRotationPivot.y);
-        }
-    }
-
     private void clear() {
         setVisibility(INVISIBLE);
         setImageDrawable(null);
-        setRotation(0);
     }
 }