ImageShow.setDefaultBackgroundColor(getResources().getColor(R.color.background_screen));
ImageSmallFilter.setDefaultBackgroundColor(getResources().getColor(R.color.background_main_toolbar));
// TODO: get those values from XML.
+ ImageZoom.setZoomedSize(getPixelsFromDip(256));
FramedTextButton.setTextSize((int) getPixelsFromDip(14));
ImageShow.setTextSize((int) getPixelsFromDip(12));
ImageShow.setTextPadding((int) getPixelsFromDip(10));
private FilterShowActivity mActivity = null;
- private static final int ORI_NORMAL = ExifInterface.ORIENTATION_NORMAL;
- private static final int ORI_ROTATE_90 = ExifInterface.ORIENTATION_ROTATE_90;
- private static final int ORI_ROTATE_180 = ExifInterface.ORIENTATION_ROTATE_180;
- private static final int ORI_ROTATE_270 = ExifInterface.ORIENTATION_ROTATE_270;
- private static final int ORI_FLIP_HOR = ExifInterface.ORIENTATION_FLIP_HORIZONTAL;
- private static final int ORI_FLIP_VERT = ExifInterface.ORIENTATION_FLIP_VERTICAL;
- private static final int ORI_TRANSPOSE = ExifInterface.ORIENTATION_TRANSPOSE;
- private static final int ORI_TRANSVERSE = ExifInterface.ORIENTATION_TRANSVERSE;
+ public static final int ORI_NORMAL = ExifInterface.ORIENTATION_NORMAL;
+ public static final int ORI_ROTATE_90 = ExifInterface.ORIENTATION_ROTATE_90;
+ public static final int ORI_ROTATE_180 = ExifInterface.ORIENTATION_ROTATE_180;
+ public static final int ORI_ROTATE_270 = ExifInterface.ORIENTATION_ROTATE_270;
+ public static final int ORI_FLIP_HOR = ExifInterface.ORIENTATION_FLIP_HORIZONTAL;
+ public static final int ORI_FLIP_VERT = ExifInterface.ORIENTATION_FLIP_VERTICAL;
+ public static final int ORI_TRANSPOSE = ExifInterface.ORIENTATION_TRANSPOSE;
+ public static final int ORI_TRANSVERSE = ExifInterface.ORIENTATION_TRANSVERSE;
private Context mContext = null;
private Uri mUri = null;
private Rect mOriginalBounds = null;
+ private static int mZoomOrientation = ORI_NORMAL;
public ImageLoader(FilterShowActivity activity, Context context) {
mActivity = activity;
mHiresCache = new DelayedPresetCache(this, 3);
}
+ public static int getZoomOrientation() {
+ return mZoomOrientation;
+ }
+
public FilterShowActivity getActivity() {
return mActivity;
}
public static Bitmap rotateToPortrait(Bitmap bitmap,int ori) {
Matrix matrix = new Matrix();
+ mZoomOrientation = ori;
int w = bitmap.getWidth();
int h = bitmap.getHeight();
if (ori == ORI_ROTATE_90 ||
import android.graphics.Matrix;
import android.graphics.RectF;
+import com.android.gallery3d.filtershow.cache.ImageLoader;
import com.android.gallery3d.filtershow.filters.ImageFilterGeometry;
-import java.util.Arrays;
-
public class GeometryMetadata {
// Applied in order: rotate, crop, scale.
// Do not scale saved image (presumably?).
if (!mCropBounds.equals(mPhotoBounds)) {
return true;
}
- if (!mFlip.equals(FLIP.NONE)){
+ if (!mFlip.equals(FLIP.NONE)) {
return true;
}
return false;
}
}
+ public Matrix getMatrixOriginalOrientation(int orientation, float originalWidth,
+ float originalHeight) {
+ Matrix imageRotation = new Matrix();
+ switch (orientation) {
+ case ImageLoader.ORI_ROTATE_90: {
+ imageRotation.setRotate(90, originalWidth / 2f, originalHeight / 2f);
+ imageRotation.postTranslate(-(originalWidth - originalHeight) / 2f,
+ -(originalHeight - originalWidth) / 2f);
+ break;
+ }
+ case ImageLoader.ORI_ROTATE_180: {
+ imageRotation.setRotate(180, originalWidth / 2f, originalHeight / 2f);
+ break;
+ }
+ case ImageLoader.ORI_ROTATE_270: {
+ imageRotation.setRotate(270, originalWidth / 2f, originalHeight / 2f);
+ imageRotation.postTranslate(-(originalWidth - originalHeight) / 2f,
+ -(originalHeight - originalWidth) / 2f);
+ break;
+ }
+ case ImageLoader.ORI_FLIP_HOR: {
+ imageRotation.preScale(-1, 1);
+ break;
+ }
+ case ImageLoader.ORI_FLIP_VERT: {
+ imageRotation.preScale(1, -1);
+ break;
+ }
+ case ImageLoader.ORI_TRANSPOSE: {
+ imageRotation.setRotate(90, originalWidth / 2f, originalHeight / 2f);
+ imageRotation.postTranslate(-(originalWidth - originalHeight) / 2f,
+ -(originalHeight - originalWidth) / 2f);
+ imageRotation.preScale(1, -1);
+ break;
+ }
+ case ImageLoader.ORI_TRANSVERSE: {
+ imageRotation.setRotate(270, originalWidth / 2f, originalHeight / 2f);
+ imageRotation.postTranslate(-(originalWidth - originalHeight) / 2f,
+ -(originalHeight - originalWidth) / 2f);
+ imageRotation.preScale(1, -1);
+ break;
+ }
+ }
+ return imageRotation;
+ }
+
+ public Matrix getOriginalToScreen(boolean rotate, float originalWidth, float originalHeight,
+ float viewWidth, float viewHeight) {
+ RectF photoBounds = getPhotoBounds();
+ RectF cropBounds = getPreviewCropBounds();
+ float imageWidth = cropBounds.width();
+ float imageHeight = cropBounds.height();
+
+ int orientation = ImageLoader.getZoomOrientation();
+ Matrix imageRotation = getMatrixOriginalOrientation(orientation, originalWidth,
+ originalHeight);
+ if (orientation == ImageLoader.ORI_ROTATE_90 ||
+ orientation == ImageLoader.ORI_ROTATE_270 ||
+ orientation == ImageLoader.ORI_TRANSPOSE ||
+ orientation == ImageLoader.ORI_TRANSVERSE) {
+ float tmp = originalWidth;
+ originalWidth = originalHeight;
+ originalHeight = tmp;
+ }
+
+ float preScale = GeometryMath.scale(originalWidth, originalHeight,
+ photoBounds.width(), photoBounds.height());
+ float scale = GeometryMath.scale(imageWidth, imageHeight, viewWidth, viewHeight);
+ // checks if local rotation is an odd multiple of 90.
+ if (((int) (getRotation() / 90)) % 2 != 0) {
+ scale = GeometryMath.scale(imageWidth, imageHeight, viewHeight, viewWidth);
+ }
+ // put in screen coordinates
+ RectF scaledCrop = GeometryMath.scaleRect(cropBounds, scale);
+ RectF scaledPhoto = GeometryMath.scaleRect(photoBounds, scale);
+ float[] displayCenter = {
+ viewWidth / 2f, viewHeight / 2f
+ };
+ Matrix m1 = GeometryMetadata.buildWanderingCropMatrix(scaledPhoto, scaledCrop,
+ getRotation(), getStraightenRotation(), getFlipType(), displayCenter);
+ float[] cropCenter = {
+ scaledCrop.centerX(), scaledCrop.centerY()
+ };
+ m1.mapPoints(cropCenter);
+ GeometryMetadata.concatRecenterMatrix(m1, cropCenter, displayCenter);
+ m1.preRotate(getStraightenRotation(), scaledPhoto.centerX(), scaledPhoto.centerY());
+ m1.preScale(scale, scale);
+ m1.preScale(preScale, preScale);
+ m1.preConcat(imageRotation);
+
+ return m1;
+ }
+
// TODO: refactor away
public Matrix getFlipMatrix(float width, float height) {
FLIP type = getFlipType();
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Matrix;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
+import com.android.gallery3d.filtershow.cache.ImageLoader;
+
public class ImageZoom extends ImageSlave {
+ private static final String LOGTAG = "ImageZoom";
private boolean mTouchDown = false;
private boolean mZoomedIn = false;
private Rect mZoomBounds = null;
+ private static float mMaxSize = 512;
public ImageZoom(Context context) {
super(context);
super(context, attrs);
}
+ public static void setZoomedSize(float size) {
+ mMaxSize = size;
+ }
+
+ @Override
+ public void resetParameter() {
+ super.resetParameter();
+ mZoomedIn = false;
+ mTouchDown = false;
+ }
+
@Override
public void onTouchDown(float x, float y) {
super.onTouchDown(x, y);
return;
}
mTouchDown = true;
- Rect originalBounds = mImageLoader.getOriginalBounds();
- Rect imageBounds = getImageBounds();
- float touchX = x - imageBounds.left;
- float touchY = y - imageBounds.top;
-
- float w = originalBounds.width();
- float h = originalBounds.height();
- float ratio = w / h;
- int mw = getWidth() / 2;
- int mh = getHeight() / 2;
- int cx = (int) (w / 2);
- int cy = (int) (h / 2);
- cx = (int) (touchX / imageBounds.width() * w);
- cy = (int) (touchY / imageBounds.height() * h);
- int left = cx - mw;
- int top = cy - mh;
- mZoomBounds = new Rect(left, top, left + mw * 2, top + mh * 2);
+ GeometryMetadata geo = getImagePreset().mGeoData;
+ Matrix originalToScreen = geo.getOriginalToScreen(true,
+ mImageLoader.getOriginalBounds().width(),
+ mImageLoader.getOriginalBounds().height(),
+ getWidth(), getHeight());
+ float[] point = new float[2];
+ point[0] = x;
+ point[1] = y;
+ Matrix inverse = new Matrix();
+ originalToScreen.invert(inverse);
+ inverse.mapPoints(point);
+
+ float ratio = (float) getWidth() / (float) getHeight();
+ float mh = mMaxSize;
+ float mw = ratio * mh;
+ RectF zoomRect = new RectF(mTouchX - mw, mTouchY - mh, mTouchX + mw, mTouchY + mw);
+ inverse.mapRect(zoomRect);
+ zoomRect.set(zoomRect.centerX() - mw, zoomRect.centerY() - mh,
+ zoomRect.centerX() + mw, zoomRect.centerY() + mh);
+ mZoomBounds = new Rect((int) zoomRect.left, (int) zoomRect.top,
+ (int) zoomRect.right, (int) zoomRect.bottom);
+ invalidate();
}
@Override
@Override
public void onDraw(Canvas canvas) {
drawBackground(canvas);
+
Bitmap filteredImage = null;
- if ((mZoomedIn ||mTouchDown) && mImageLoader != null) {
- filteredImage = mImageLoader.getScaleOneImageForPreset(this, getImagePreset(), mZoomBounds, false);
+ if ((mZoomedIn || mTouchDown) && mImageLoader != null) {
+ filteredImage = mImageLoader.getScaleOneImageForPreset(this, getImagePreset(),
+ mZoomBounds, false);
} else {
requestFilteredImages();
filteredImage = getFilteredImage();
}
+ canvas.save();
+ if (mZoomedIn || mTouchDown) {
+ int orientation = ImageLoader.getZoomOrientation();
+ switch (orientation) {
+ case ImageLoader.ORI_ROTATE_90: {
+ canvas.rotate(90, getWidth() / 2, getHeight() / 2);
+ break;
+ }
+ case ImageLoader.ORI_ROTATE_270: {
+ canvas.rotate(270, getWidth() / 2, getHeight() / 2);
+ break;
+ }
+ case ImageLoader.ORI_TRANSPOSE: {
+ canvas.rotate(90, getWidth() / 2, getHeight() / 2);
+ canvas.scale(1, -1);
+ break;
+ }
+ case ImageLoader.ORI_TRANSVERSE: {
+ canvas.rotate(270, getWidth() / 2, getHeight() / 2);
+ canvas.scale(1, -1);
+ break;
+ }
+ }
+ }
drawImage(canvas, filteredImage);
+ canvas.restore();
+
if (showControls()) {
mSliderController.onDraw(canvas);
}
invalidate();
return false;
}
-}
\ No newline at end of file
+}