summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRuben Brunk <rubenbrunk@google.com>2013-04-18 16:22:27 -0700
committerRuben Brunk <rubenbrunk@google.com>2013-04-18 16:28:56 -0700
commit8cb7055c0ea13b7b219e2cdc46cbfbf62e97c96e (patch)
tree9ac4c76b6a5e1b60940d1efc154d09b17c8f6b9b /src
parentb0e82433a948ab7625d5c0343a4207ea9a45bbf7 (diff)
downloadandroid_packages_apps_Snap-8cb7055c0ea13b7b219e2cdc46cbfbf62e97c96e.tar.gz
android_packages_apps_Snap-8cb7055c0ea13b7b219e2cdc46cbfbf62e97c96e.tar.bz2
android_packages_apps_Snap-8cb7055c0ea13b7b219e2cdc46cbfbf62e97c96e.zip
Fix crop activity aspect ratio and orientation handling.
Bug: 8659064 Bug: 8647628 Change-Id: I3e4293cc3bba7d55334acb396e20a23cc92f8f82
Diffstat (limited to 'src')
-rw-r--r--src/com/android/gallery3d/filtershow/crop/CropActivity.java85
-rw-r--r--src/com/android/gallery3d/filtershow/crop/CropLoader.java25
-rw-r--r--src/com/android/gallery3d/filtershow/crop/CropObject.java2
-rw-r--r--src/com/android/gallery3d/filtershow/crop/CropView.java20
4 files changed, 88 insertions, 44 deletions
diff --git a/src/com/android/gallery3d/filtershow/crop/CropActivity.java b/src/com/android/gallery3d/filtershow/crop/CropActivity.java
index 878b82fc6..3429e0baf 100644
--- a/src/com/android/gallery3d/filtershow/crop/CropActivity.java
+++ b/src/com/android/gallery3d/filtershow/crop/CropActivity.java
@@ -25,6 +25,7 @@ import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.BitmapRegionDecoder;
+import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.RectF;
import android.net.Uri;
@@ -58,12 +59,12 @@ public class CropActivity extends Activity {
private Bitmap mOriginalBitmap = null;
private RectF mOriginalBounds = null;
+ private int mOriginalRotation = 0;
private Uri mSourceUri = null;
private CropView mCropView = null;
private View mSaveButton = null;
private boolean finalIOGuard = false;
- private Intent mResultIntent = null;
private static final int SELECT_PICTURE = 1; // request code for picker
private static final int DEFAULT_COMPRESS_QUALITY = 90;
@@ -80,8 +81,7 @@ public class CropActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
- mResultIntent = new Intent();
- setResult(RESULT_CANCELED, mResultIntent);
+ setResult(RESULT_CANCELED, new Intent());
mCropExtras = getExtrasFromIntent(intent);
if (mCropExtras != null && mCropExtras.getShowWhenLocked()) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
@@ -160,24 +160,42 @@ public class CropActivity extends Activity {
* Method that loads a bitmap in an async task.
*/
private void startLoadBitmap(Uri uri) {
- enableSave(false);
- final View loading = findViewById(R.id.loading);
- loading.setVisibility(View.VISIBLE);
- mLoadBitmapTask = new LoadBitmapTask();
- mLoadBitmapTask.execute(uri);
+ if (uri != null) {
+ enableSave(false);
+ final View loading = findViewById(R.id.loading);
+ loading.setVisibility(View.VISIBLE);
+ mLoadBitmapTask = new LoadBitmapTask();
+ mLoadBitmapTask.execute(uri);
+ } else {
+ cannotLoadImage();
+ done();
+ }
}
/**
* Method called on UI thread with loaded bitmap.
*/
- private void doneLoadBitmap(Bitmap bitmap, RectF bounds) {
+ private void doneLoadBitmap(Bitmap bitmap, RectF bounds, int orientation) {
final View loading = findViewById(R.id.loading);
loading.setVisibility(View.GONE);
mOriginalBitmap = bitmap;
mOriginalBounds = bounds;
+ mOriginalRotation = orientation;
if (bitmap != null && bitmap.getWidth() != 0 && bitmap.getHeight() != 0) {
RectF imgBounds = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());
- mCropView.initialize(bitmap, imgBounds, imgBounds, 0);
+ mCropView.initialize(bitmap, imgBounds, imgBounds, orientation);
+ if (mCropExtras != null) {
+ int aspectX = mCropExtras.getAspectX();
+ int aspectY = mCropExtras.getAspectY();
+ int outputX = mCropExtras.getOutputX();
+ int outputY = mCropExtras.getOutputY();
+ if (outputX > 0 && outputY > 0) {
+ mCropView.applyAspect(outputX, outputY);
+ }
+ if (aspectX > 0 && aspectY > 0) {
+ mCropView.applyAspect(aspectX, aspectY);
+ }
+ }
enableSave(true);
} else {
Log.w(LOGTAG, "could not load image for cropping");
@@ -206,23 +224,27 @@ public class CropActivity extends Activity {
int mBitmapSize;
Context mContext;
Rect mOriginalBounds;
+ int mOrientation;
public LoadBitmapTask() {
mBitmapSize = getScreenImageSize();
mContext = getApplicationContext();
mOriginalBounds = new Rect();
+ mOrientation = 0;
}
@Override
protected Bitmap doInBackground(Uri... params) {
- Bitmap bmap = CropLoader.getConstrainedBitmap(params[0], mContext, mBitmapSize,
+ Uri uri = params[0];
+ Bitmap bmap = CropLoader.getConstrainedBitmap(uri, mContext, mBitmapSize,
mOriginalBounds);
+ mOrientation = CropLoader.getMetadataRotation(uri, mContext);
return bmap;
}
@Override
protected void onPostExecute(Bitmap result) {
- doneLoadBitmap(result, new RectF(mOriginalBounds));
+ doneLoadBitmap(result, new RectF(mOriginalBounds), mOrientation);
}
}
@@ -258,16 +280,17 @@ public class CropActivity extends Activity {
RectF crop = getBitmapCrop(photo);
startBitmapIO(flags, mOriginalBitmap, mSourceUri, destinationUri, crop,
photo, mOriginalBounds,
- (mCropExtras == null) ? null : mCropExtras.getOutputFormat());
+ (mCropExtras == null) ? null : mCropExtras.getOutputFormat(), mOriginalRotation);
return;
}
- setResult(RESULT_CANCELED, mResultIntent);
+ setResult(RESULT_CANCELED, new Intent());
done();
return;
}
private void startBitmapIO(int flags, Bitmap currentBitmap, Uri sourceUri, Uri destUri,
- RectF cropBounds, RectF photoBounds, RectF currentBitmapBounds, String format) {
+ RectF cropBounds, RectF photoBounds, RectF currentBitmapBounds, String format,
+ int rotation) {
if (cropBounds == null || photoBounds == null || currentBitmap == null
|| currentBitmap.getWidth() == 0 || currentBitmap.getHeight() == 0
|| cropBounds.width() == 0 || cropBounds.height() == 0 || photoBounds.width() == 0
@@ -284,7 +307,7 @@ public class CropActivity extends Activity {
final View loading = findViewById(R.id.loading);
loading.setVisibility(View.VISIBLE);
BitmapIOTask ioTask = new BitmapIOTask(sourceUri, destUri, format, flags, cropBounds,
- photoBounds, currentBitmapBounds);
+ photoBounds, currentBitmapBounds, rotation);
ioTask.execute(currentBitmap);
}
@@ -312,9 +335,10 @@ public class CropActivity extends Activity {
RectF mPhoto = null;
RectF mOrig = null;
Intent mResultIntent = null;
+ int mRotation = 0;
public BitmapIOTask(Uri sourceUri, Uri destUri, String outputFormat, int flags,
- RectF cropBounds, RectF photoBounds, RectF originalBitmapBounds) {
+ RectF cropBounds, RectF photoBounds, RectF originalBitmapBounds, int rotation) {
mOutputFormat = outputFormat;
mOutStream = null;
mOutUri = destUri;
@@ -325,6 +349,9 @@ public class CropActivity extends Activity {
mOrig = originalBitmapBounds;
mWPManager = WallpaperManager.getInstance(getApplicationContext());
mResultIntent = new Intent();
+ mRotation = (rotation < 0) ? -rotation : rotation;
+ mRotation %= 360;
+ mRotation = 90 * (int) (mRotation / 90); // now mRotation is a multiple of 90
if ((flags & DO_EXTRA_OUTPUT) != 0) {
if (mOutUri == null) {
@@ -359,6 +386,9 @@ public class CropActivity extends Activity {
// Set extra for crop bounds
if (mCrop != null && mPhoto != null && mOrig != null) {
RectF trueCrop = CropMath.getScaledCropBounds(mCrop, mPhoto, mOrig);
+ Matrix m = new Matrix();
+ m.setRotate(mRotation);
+ m.mapRect(trueCrop);
if (trueCrop != null) {
Rect rounded = new Rect();
trueCrop.roundOut(rounded);
@@ -377,6 +407,15 @@ public class CropActivity extends Activity {
Log.w(LOGTAG, "could not downsample bitmap to return in data");
failure = true;
} else {
+ if (mRotation > 0) {
+ Matrix m = new Matrix();
+ m.setRotate(mRotation);
+ Bitmap tmp = Bitmap.createBitmap(ret, 0, 0, ret.getWidth(),
+ ret.getHeight(), m, true);
+ if (tmp != null) {
+ ret = tmp;
+ }
+ }
mResultIntent.putExtra(CropExtras.KEY_DATA, ret);
}
}
@@ -420,6 +459,15 @@ public class CropActivity extends Activity {
failure = true;
return false;
}
+ if (mRotation > 0) {
+ Matrix m = new Matrix();
+ m.setRotate(mRotation);
+ Bitmap tmp = Bitmap.createBitmap(crop, 0, 0, crop.getWidth(),
+ crop.getHeight(), m, true);
+ if (tmp != null) {
+ crop = tmp;
+ }
+ }
// Get output compression format
CompressFormat cf =
convertExtensionToCompressFormat(getFileExtension(mOutputFormat));
@@ -430,6 +478,8 @@ public class CropActivity extends Activity {
|| !crop.compress(cf, DEFAULT_COMPRESS_QUALITY, mOutStream)) {
Log.w(LOGTAG, "failed to compress bitmap to file: " + mOutUri.toString());
failure = true;
+ } else {
+ mResultIntent.setData(mOutUri);
}
} else {
// Compress to byte array
@@ -446,6 +496,7 @@ public class CropActivity extends Activity {
} else {
try {
mOutStream.write(tmpOut.toByteArray());
+ mResultIntent.setData(mOutUri);
} catch (IOException e) {
Log.w(LOGTAG,
"failed to compress bitmap to file: "
diff --git a/src/com/android/gallery3d/filtershow/crop/CropLoader.java b/src/com/android/gallery3d/filtershow/crop/CropLoader.java
index 2eb1a14ac..fc461f5d0 100644
--- a/src/com/android/gallery3d/filtershow/crop/CropLoader.java
+++ b/src/com/android/gallery3d/filtershow/crop/CropLoader.java
@@ -48,13 +48,10 @@ import java.text.SimpleDateFormat;
public abstract class CropLoader {
public static final String LOGTAG = "CropLoader";
public static final String JPEG_MIME_TYPE = "image/jpeg";
- public static final int ORI_NORMAL = ExifInterface.Orientation.TOP_LEFT;
- public static final int ORI_ROTATE_90 = ExifInterface.Orientation.RIGHT_TOP;
- public static final int ORI_ROTATE_180 = ExifInterface.Orientation.BOTTOM_LEFT;
- public static final int ORI_ROTATE_270 = ExifInterface.Orientation.RIGHT_BOTTOM;
private static final String TIME_STAMP_NAME = "'IMG'_yyyyMMdd_HHmmss";
public static final String DEFAULT_SAVE_DIRECTORY = "EditedOnlinePhotos";
+
/**
* Returns the orientation of image at the given URI as one of 0, 90, 180,
* 270.
@@ -63,7 +60,7 @@ public abstract class CropLoader {
* @param context context whose ContentResolver to use.
* @return the orientation of the image. Defaults to 0.
*/
- public static int getMetadataOrientation(Uri uri, Context context) {
+ public static int getMetadataRotation(Uri uri, Context context) {
if (uri == null || context == null) {
throw new IllegalArgumentException("bad argument to getScaledBitmap");
}
@@ -87,25 +84,11 @@ public abstract class CropLoader {
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri,
- new String[] {
- MediaStore.Images.ImageColumns.ORIENTATION
- },
+ new String[] { MediaStore.Images.ImageColumns.ORIENTATION },
null, null, null);
if (cursor.moveToNext()) {
int ori = cursor.getInt(0);
-
- switch (ori) {
- case 0:
- return ORI_NORMAL;
- case 90:
- return ORI_ROTATE_90;
- case 270:
- return ORI_ROTATE_270;
- case 180:
- return ORI_ROTATE_180;
- default:
- return 0;
- }
+ return (ori < 0) ? 0 : ori;
}
} catch (SQLiteException e) {
return 0;
diff --git a/src/com/android/gallery3d/filtershow/crop/CropObject.java b/src/com/android/gallery3d/filtershow/crop/CropObject.java
index 7999b4878..bea3ffabd 100644
--- a/src/com/android/gallery3d/filtershow/crop/CropObject.java
+++ b/src/com/android/gallery3d/filtershow/crop/CropObject.java
@@ -89,7 +89,7 @@ public class CropObject {
clearSelectState();
}
- public boolean setInnerAspectRatio(int width, int height) {
+ public boolean setInnerAspectRatio(float width, float height) {
if (width <= 0 || height <= 0) {
throw new IllegalArgumentException("Width and Height must be greater than zero");
}
diff --git a/src/com/android/gallery3d/filtershow/crop/CropView.java b/src/com/android/gallery3d/filtershow/crop/CropView.java
index 56579f4dc..dca752146 100644
--- a/src/com/android/gallery3d/filtershow/crop/CropView.java
+++ b/src/com/android/gallery3d/filtershow/crop/CropView.java
@@ -186,16 +186,26 @@ public class CropView extends View {
public void applyOriginalAspect() {
RectF outer = mCropObj.getOuterBounds();
- if (!mCropObj.setInnerAspectRatio((int) outer.width(), (int) outer.height())) {
+ float w = outer.width();
+ float h = outer.height();
+ if (w > 0 && h > 0) {
+ applyAspect(w, h);
+ mCropObj.resetBoundsTo(outer, outer);
+ } else {
Log.w(LOGTAG, "failed to set aspect ratio original");
}
- mCropObj.resetBoundsTo(outer, outer);
- invalidate();
}
public void applySquareAspect() {
- if (!mCropObj.setInnerAspectRatio(1, 1)) {
- Log.w(LOGTAG, "failed to set aspect ratio square");
+ applyAspect(1, 1);
+ }
+
+ public void applyAspect(float x, float y) {
+ if (x <= 0 || y <= 0) {
+ throw new IllegalArgumentException("Bad arguments to applyAspect");
+ }
+ if (!mCropObj.setInnerAspectRatio(x, y)) {
+ Log.w(LOGTAG, "failed to set aspect ratio");
}
invalidate();
}