Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Added resizing with keeping aspect ratio when dimension is 0.
  • Loading branch information
mcharmas committed Oct 24, 2014
commit 2007bde3a837c3ae9300b4270793fba030189709
9 changes: 6 additions & 3 deletions picasso/src/main/java/com/squareup/picasso/BitmapHunter.java
Original file line number Diff line number Diff line change
Expand Up @@ -463,12 +463,15 @@ static Bitmap transformResult(Request data, Bitmap result, int exifRotation) {
float heightRatio = targetHeight / (float) inHeight;
float scale = widthRatio < heightRatio ? widthRatio : heightRatio;
matrix.preScale(scale, scale);
} else if (targetWidth != 0 && targetHeight != 0 //
} else if ((targetWidth != 0 || targetHeight != 0) //
&& (targetWidth != inWidth || targetHeight != inHeight)) {
// If an explicit target size has been specified and they do not match the results bounds,
// pre-scale the existing matrix appropriately.
float sx = targetWidth / (float) inWidth;
float sy = targetHeight / (float) inHeight;
// Keep aspect ratio if one dimension is set to 0.
float sx = targetWidth != 0 ? targetWidth / (float) inWidth
: targetHeight / (float) inHeight;
float sy = targetHeight != 0 ? targetHeight / (float) inHeight
: targetWidth / (float) inWidth;
matrix.preScale(sx, sy);
}
}
Expand Down
32 changes: 20 additions & 12 deletions picasso/src/main/java/com/squareup/picasso/Request.java
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,15 @@ String getName() {
}

public boolean hasSize() {
return targetWidth != 0;
return targetWidth != 0 || targetHeight != 0;
}

boolean needsTransformation() {
return needsMatrixTransform() || hasCustomTransformations();
}

boolean needsMatrixTransform() {
return targetWidth != 0 || rotationDegrees != 0;
return hasSize() || rotationDegrees != 0;
}

boolean hasCustomTransformations() {
Expand Down Expand Up @@ -230,7 +230,7 @@ boolean hasImage() {
}

boolean hasSize() {
return targetWidth != 0;
return targetWidth != 0 || targetHeight != 0;
}

boolean hasPriority() {
Expand Down Expand Up @@ -265,13 +265,19 @@ public Builder setResourceId(int resourceId) {
return this;
}

/** Resize the image to the specified size in pixels. */
/**
* Resize the image to the specified size in pixels.
* Use 0 as desired dimension to resize keeping aspect ratio.
*/
public Builder resize(int targetWidth, int targetHeight) {
if (targetWidth <= 0) {
throw new IllegalArgumentException("Width must be positive number.");
if (targetWidth < 0) {
throw new IllegalArgumentException("Width must be positive number or 0.");
}
if (targetHeight < 0) {
throw new IllegalArgumentException("Height must be positive number or 0.");
}
if (targetHeight <= 0) {
throw new IllegalArgumentException("Height must be positive number.");
if (targetHeight == 0 && targetWidth == 0) {
throw new IllegalArgumentException("At least one dimension has to be positive number.");
}
this.targetWidth = targetWidth;
this.targetHeight = targetHeight;
Expand Down Expand Up @@ -390,11 +396,13 @@ public Request build() {
if (centerInside && centerCrop) {
throw new IllegalStateException("Center crop and center inside can not be used together.");
}
if (centerCrop && targetWidth == 0) {
throw new IllegalStateException("Center crop requires calling resize.");
if (centerCrop && (targetWidth == 0 || targetHeight == 0)) {
throw new IllegalStateException(
"Center crop requires calling resize with positive width and height.");
}
if (centerInside && targetWidth == 0) {
throw new IllegalStateException("Center inside requires calling resize.");
if (centerInside && (targetWidth == 0 || targetHeight == 0)) {
throw new IllegalStateException(
"Center inside requires calling resize with positive width and height.");
}
if (priority == null) {
priority = Priority.NORMAL;
Expand Down
18 changes: 13 additions & 5 deletions picasso/src/main/java/com/squareup/picasso/RequestHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,19 @@ static void calculateInSampleSize(int reqWidth, int reqHeight, int width, int he
BitmapFactory.Options options, Request request) {
int sampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int heightRatio = (int) Math.floor((float) height / (float) reqHeight);
final int widthRatio = (int) Math.floor((float) width / (float) reqWidth);
sampleSize = request.centerInside
? Math.max(heightRatio, widthRatio)
: Math.min(heightRatio, widthRatio);
final int heightRatio;
final int widthRatio;
if (reqHeight == 0) {
sampleSize = (int) Math.floor((float) width / (float) reqWidth);
} else if (reqWidth == 0) {
sampleSize = (int) Math.floor((float) height / (float) reqHeight);
} else {
heightRatio = (int) Math.floor((float) height / (float) reqHeight);
widthRatio = (int) Math.floor((float) width / (float) reqWidth);
sampleSize = request.centerInside
? Math.max(heightRatio, widthRatio)
: Math.min(heightRatio, widthRatio);
}
}
options.inSampleSize = sampleSize;
options.inJustDecodeBounds = false;
Expand Down
2 changes: 1 addition & 1 deletion picasso/src/main/java/com/squareup/picasso/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ static String createKey(Request data, StringBuilder builder) {
}
builder.append('\n');
}
if (data.targetWidth != 0) {
if (data.hasSize()) {
builder.append("resize:").append(data.targetWidth).append('x').append(data.targetHeight);
builder.append('\n');
}
Expand Down
24 changes: 24 additions & 0 deletions picasso/src/test/java/com/squareup/picasso/BitmapHunterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,30 @@ public class BitmapHunterTest {
assertThat(shadowMatrix.getPreOperations()).containsOnly("rotate 90.0");
}

@Test public void keepsAspectRationWhileResizingWhenDesiredWidthIs0() throws Exception {
Request request = new Request.Builder(URI_1).resize(20, 0).build();
Bitmap source = Bitmap.createBitmap(40, 20, ARGB_8888);

Bitmap result = transformResult(request, source, 0);

ShadowBitmap shadowBitmap = shadowOf(result);
Matrix matrix = shadowBitmap.getCreatedFromMatrix();
ShadowMatrix shadowMatrix = shadowOf(matrix);
assertThat(shadowMatrix.getPreOperations()).containsOnly("scale 0.5 0.5");
}

@Test public void keepsAspectRationWhileResizingWhenDesiredHeighIs0() throws Exception {
Request request = new Request.Builder(URI_1).resize(0, 10).build();
Bitmap source = Bitmap.createBitmap(40, 20, ARGB_8888);

Bitmap result = transformResult(request, source, 0);

ShadowBitmap shadowBitmap = shadowOf(result);
Matrix matrix = shadowBitmap.getCreatedFromMatrix();
ShadowMatrix shadowMatrix = shadowOf(matrix);
assertThat(shadowMatrix.getPreOperations()).containsOnly("scale 0.5 0.5");
}

@Test public void exifRotationWithManualRotation() throws Exception {
Bitmap source = Bitmap.createBitmap(10, 10, ARGB_8888);
Request data = new Request.Builder(URI_1).rotate(-45).build();
Expand Down
35 changes: 27 additions & 8 deletions picasso/src/test/java/com/squareup/picasso/RequestCreatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,31 @@ public void intoRemoteViewsNotificationWithFitThrows() {
}
}

@Test public void appWidgetActionWithDefaultPriority() {
@Test
public void intoTargetResizeWith0WithCenterInsideOrCenterCropThrows() {
try {
new RequestCreator(picasso, URI_1, 0).resize(0, 10).centerInside().into(mockTarget());
fail("Center inside with unknown width should throw exception.");
} catch (IllegalStateException ignored) {
}
try {
new RequestCreator(picasso, URI_1, 0).resize(10, 0).centerInside().into(mockTarget());
fail("Center inside with unknown height should throw exception.");
} catch (IllegalStateException ignored) {
}
try {
new RequestCreator(picasso, URI_1, 0).resize(0, 10).centerCrop().into(mockTarget());
fail("Center inside with unknown width should throw exception.");
} catch (IllegalStateException ignored) {
}
try {
new RequestCreator(picasso, URI_1, 0).resize(10, 0).centerCrop().into(mockTarget());
fail("Center inside with unknown height should throw exception.");
} catch (IllegalStateException ignored) {
}
}

@Test public void appWidgetActionWithDefaultPriority() throws Exception {
new RequestCreator(picasso, URI_1, 0).into(mockRemoteViews(), 0, new int[] { 1, 2, 3 });
verify(picasso).enqueueAndSubmit(actionCaptor.capture());
assertThat(actionCaptor.getValue().getPriority()).isEqualTo(NORMAL);
Expand Down Expand Up @@ -578,13 +602,8 @@ public void intoRemoteViewsNotificationWithFitThrows() {
} catch (IllegalArgumentException ignored) {
}
try {
new RequestCreator().resize(0, 10);
fail("Zero width should throw exception.");
} catch (IllegalArgumentException ignored) {
}
try {
new RequestCreator().resize(10, 0);
fail("Zero height should throw exception.");
new RequestCreator().resize(0, 0);
fail("Zero dimensions should throw exception.");
} catch (IllegalArgumentException ignored) {
}
}
Expand Down
14 changes: 14 additions & 0 deletions picasso/src/test/java/com/squareup/picasso/RequestHandlerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,20 @@ public class RequestHandlerTest {
assertThat(options.inSampleSize).isEqualTo(4);
}

@Test public void calculateInSampleSizeKeepAspectRatioWithWidth() {
final BitmapFactory.Options options = new BitmapFactory.Options();
Request data = new Request.Builder(URI_1).resize(400, 0).build();
calculateInSampleSize(data.targetWidth, data.targetHeight, 800, 200, options, data);
assertThat(options.inSampleSize).isEqualTo(2);
}

@Test public void calculateInSampleSizeKeepAspectRatioWithHeight() {
final BitmapFactory.Options options = new BitmapFactory.Options();
Request data = new Request.Builder(URI_1).resize(0, 100).build();
calculateInSampleSize(data.targetWidth, data.targetHeight, 800, 200, options, data);
assertThat(options.inSampleSize).isEqualTo(2);
}

@Test public void nullBitmapOptionsIfNoResizing() {
// No resize must return no bitmap options
final Request noResize = new Request.Builder(URI_1).build();
Expand Down