summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Kung <kingkung@google.com>2014-09-10 13:04:55 -0700
committerJames Kung <kingkung@google.com>2014-09-10 13:54:48 -0700
commit3a79e2002f9f6114b549c4bc2cc08bb10e75a4d2 (patch)
tree6cb75e8bd2bb89134a95521784c4542da2c23c48
parentd05e64cf9f9b1542ccdac8675c63b8b185c97a48 (diff)
downloadbitmap-3a79e2002f9f6114b549c4bc2cc08bb10e75a4d2.tar.gz
Allow user to choose horizontal crop alignment
Bug: 17272990 Change-Id: I8622d7e837dc1045a9b41c86dc91727bf152c8d3
-rw-r--r--src/com/android/bitmap/DecodeTask.java34
-rw-r--r--src/com/android/bitmap/drawable/BasicBitmapDrawable.java15
-rw-r--r--src/com/android/bitmap/drawable/ExtendedBitmapDrawable.java20
-rw-r--r--src/com/android/bitmap/util/BitmapUtils.java14
4 files changed, 70 insertions, 13 deletions
diff --git a/src/com/android/bitmap/DecodeTask.java b/src/com/android/bitmap/DecodeTask.java
index ac08c0b..0f12bae 100644
--- a/src/com/android/bitmap/DecodeTask.java
+++ b/src/com/android/bitmap/DecodeTask.java
@@ -323,8 +323,8 @@ public class DecodeTask extends AsyncTask<Void, Void, ReusableBitmap> {
// if" the orientation has been corrected.
// Center the decode on the top 1/3.
BitmapUtils.calculateCroppedSrcRect(srcW, srcH, mDecodeOpts.destW,
- mDecodeOpts.destH,
- mDecodeOpts.destH, mOpts.inSampleSize, mDecodeOpts.verticalCenter,
+ mDecodeOpts.destH, mDecodeOpts.destH, mOpts.inSampleSize,
+ mDecodeOpts.horizontalCenter, mDecodeOpts.verticalCenter,
true /* absoluteFraction */,
1f, srcRect);
if (DEBUG) {
@@ -553,6 +553,12 @@ public class DecodeTask extends AsyncTask<Void, Void, ReusableBitmap> {
public int destH;
/**
* If the destination dimensions are smaller than the source image provided by the request
+ * key, this will determine where horizontally the destination rect will be cropped from.
+ * Value from 0f for left-most crop to 1f for right-most crop.
+ */
+ public float horizontalCenter;
+ /**
+ * If the destination dimensions are smaller than the source image provided by the request
* key, this will determine where vertically the destination rect will be cropped from.
* Value from 0f for top-most crop to 1f for bottom-most crop.
*/
@@ -563,22 +569,40 @@ public class DecodeTask extends AsyncTask<Void, Void, ReusableBitmap> {
public int sampleSizeStrategy;
public DecodeOptions(final int destW, final int destH) {
- this(destW, destH, 0.5f, STRATEGY_ROUND_NEAREST);
+ this(destW, destH, 0.5f, 0.5f, STRATEGY_ROUND_NEAREST);
+ }
+
+ /**
+ * Create new DecodeOptions with horizontally-centered cropping if applicable.
+ * @param destW The destination width to decode to.
+ * @param destH The destination height to decode to.
+ * @param verticalCenter If the destination dimensions are smaller than the source image
+ * provided by the request key, this will determine where vertically
+ * the destination rect will be cropped from.
+ * @param sampleSizeStrategy One of the STRATEGY constants.
+ */
+ public DecodeOptions(final int destW, final int destH,
+ final float verticalCenter, final int sampleSizeStrategy) {
+ this(destW, destH, 0.5f, verticalCenter, sampleSizeStrategy);
}
/**
* Create new DecodeOptions.
* @param destW The destination width to decode to.
* @param destH The destination height to decode to.
+ * @param horizontalCenter If the destination dimensions are smaller than the source image
+ * provided by the request key, this will determine where
+ * horizontally the destination rect will be cropped from.
* @param verticalCenter If the destination dimensions are smaller than the source image
* provided by the request key, this will determine where vertically
* the destination rect will be cropped from.
* @param sampleSizeStrategy One of the STRATEGY constants.
*/
- public DecodeOptions(final int destW, final int destH, final float verticalCenter,
- final int sampleSizeStrategy) {
+ public DecodeOptions(final int destW, final int destH, final float horizontalCenter,
+ final float verticalCenter, final int sampleSizeStrategy) {
this.destW = destW;
this.destH = destH;
+ this.horizontalCenter = horizontalCenter;
this.verticalCenter = verticalCenter;
this.sampleSizeStrategy = sampleSizeStrategy;
}
diff --git a/src/com/android/bitmap/drawable/BasicBitmapDrawable.java b/src/com/android/bitmap/drawable/BasicBitmapDrawable.java
index d637a98..3ecc15b 100644
--- a/src/com/android/bitmap/drawable/BasicBitmapDrawable.java
+++ b/src/com/android/bitmap/drawable/BasicBitmapDrawable.java
@@ -86,6 +86,7 @@ public class BasicBitmapDrawable extends Drawable implements DecodeCallback,
private static final int MAX_BITMAP_DENSITY = DisplayMetrics.DENSITY_HIGH;
private static final float VERTICAL_CENTER = 1f / 2;
+ private static final float HORIZONTAL_CENTER = 1f / 2;
private static final float NO_MULTIPLIER = 1f;
private static final String TAG = BasicBitmapDrawable.class.getSimpleName();
@@ -303,8 +304,8 @@ public class BasicBitmapDrawable extends Drawable implements DecodeCallback,
if (mTask != null) {
mTask.cancel();
}
- final DecodeOptions opts = new DecodeOptions(bufferW, bufferH, getDecodeVerticalCenter(),
- getDecodeStrategy());
+ final DecodeOptions opts = new DecodeOptions(bufferW, bufferH, getDecodeHorizontalCenter(),
+ getDecodeVerticalCenter(), getDecodeStrategy());
mTask = new DecodeTask(mCurrKey, opts, factory, this, mCache);
mTask.executeOnExecutor(getExecutor());
Trace.endSection();
@@ -333,6 +334,14 @@ public class BasicBitmapDrawable extends Drawable implements DecodeCallback,
* Clients can override this to specify which section of the source image to decode from.
* Possible applications include using face detection to always decode around facial features.
*/
+ protected float getDecodeHorizontalCenter() {
+ return HORIZONTAL_CENTER;
+ }
+
+ /**
+ * Clients can override this to specify which section of the source image to decode from.
+ * Possible applications include using face detection to always decode around facial features.
+ */
protected float getDecodeVerticalCenter() {
return VERTICAL_CENTER;
}
@@ -348,7 +357,7 @@ public class BasicBitmapDrawable extends Drawable implements DecodeCallback,
BitmapUtils.calculateCroppedSrcRect(
mBitmap.getLogicalWidth(), mBitmap.getLogicalHeight(),
bounds.width(), bounds.height(),
- bounds.height(), Integer.MAX_VALUE,
+ bounds.height(), Integer.MAX_VALUE, getDecodeHorizontalCenter(),
getDrawVerticalCenter(), false /* absoluteFraction */,
getDrawVerticalOffsetMultiplier(), sRect);
diff --git a/src/com/android/bitmap/drawable/ExtendedBitmapDrawable.java b/src/com/android/bitmap/drawable/ExtendedBitmapDrawable.java
index ab81e6f..fc54419 100644
--- a/src/com/android/bitmap/drawable/ExtendedBitmapDrawable.java
+++ b/src/com/android/bitmap/drawable/ExtendedBitmapDrawable.java
@@ -246,6 +246,11 @@ public class ExtendedBitmapDrawable extends BasicBitmapDrawable implements
}
@Override
+ protected float getDecodeHorizontalCenter() {
+ return mOpts.decodeHorizontalCenter;
+ }
+
+ @Override
protected float getDecodeVerticalCenter() {
return mOpts.decodeVerticalCenter;
}
@@ -690,6 +695,16 @@ public class ExtendedBitmapDrawable extends BasicBitmapDrawable implements
* Optional field for general decoding.
*
* This field determines which section of the source image to decode from. A value of 0
+ * indicates a preference for the far left of the source, while a value of 1 indicates a
+ * preference for the far right of the source. A value of .5 will result in the center
+ * of the source being decoded.
+ */
+ public float decodeHorizontalCenter = 1f / 2;
+
+ /**
+ * Optional field for general decoding.
+ *
+ * This field determines which section of the source image to decode from. A value of 0
* indicates a preference for the very top of the source, while a value of 1 indicates a
* preference for the very bottom of the source. A value of .5 will result in the center
* of the source being decoded.
@@ -778,6 +793,11 @@ public class ExtendedBitmapDrawable extends BasicBitmapDrawable implements
*/
private void validate()
throws IllegalStateException {
+ if (decodeHorizontalCenter < 0 || decodeHorizontalCenter > 1) {
+ throw new IllegalStateException(
+ "ExtendedOptions: decodeHorizontalCenter must be within 0 and 1, " +
+ "inclusive");
+ }
if (decodeVerticalCenter < 0 || decodeVerticalCenter > 1) {
throw new IllegalStateException(
"ExtendedOptions: decodeVerticalCenter must be within 0 and 1, inclusive");
diff --git a/src/com/android/bitmap/util/BitmapUtils.java b/src/com/android/bitmap/util/BitmapUtils.java
index 094d771..9ec466b 100644
--- a/src/com/android/bitmap/util/BitmapUtils.java
+++ b/src/com/android/bitmap/util/BitmapUtils.java
@@ -21,8 +21,8 @@ import android.graphics.Rect;
public abstract class BitmapUtils {
/**
- * Calculate a center-crop rectangle for the given input and output
- * parameters. The output rectangle to use is written in the given outRect.
+ * Calculate a rectangle for the given input and output parameters. The output
+ * rectangle to use is written in the given outRect.
*
* @param srcW the source width
* @param srcH the source height
@@ -34,6 +34,9 @@ public abstract class BitmapUtils {
* vertical crop range.
* @param sampleSize a scaling factor that rect calculation will only use if
* it's more aggressive than regular scaling
+ * @param horizSliceFrac horizontal slice fraction determines the horizontal
+ * center point for the crop rect. Range is from [0.0, 1.0]. To
+ * perform a horizontally centered crop, use 0.5.
* @param vertSliceFrac vertical slice fraction determines the vertical
* center point for the crop rect. Range is from [0.0, 1.0]. To
* perform a vertically centered crop, use 0.5. Otherwise, see
@@ -52,8 +55,9 @@ public abstract class BitmapUtils {
* @param outRect a Rect to write the resulting crop coordinates into
*/
public static void calculateCroppedSrcRect(final int srcW, final int srcH, final int dstW,
- final int dstH, final int dstSliceH, int sampleSize, final float vertSliceFrac,
- final boolean absoluteFrac, final float verticalMultiplier, final Rect outRect) {
+ final int dstH, final int dstSliceH, int sampleSize, final float horizSliceFrac,
+ final float vertSliceFrac, final boolean absoluteFrac, final float verticalMultiplier,
+ final Rect outRect) {
if (sampleSize < 1) {
sampleSize = 1;
}
@@ -73,7 +77,7 @@ public abstract class BitmapUtils {
final int srcCroppedSliceH = Math.round(dstSliceH * scale);
final int srcHalfSliceH = Math.min(srcCroppedSliceH, srcH) / 2;
- outRect.left = (srcW - srcCroppedW) / 2;
+ outRect.left = (int) (horizSliceFrac * (srcW - srcCroppedW));
outRect.right = outRect.left + srcCroppedW;
final int centerV;