Skip to content

Commit 4d4a79c

Browse files
committed
Merge pull request #663 from mcharmas/master
Added resizing with keeping aspect ratio when dimension is 0.
2 parents 249e8f6 + 2007bde commit 4d4a79c

File tree

7 files changed

+105
-29
lines changed

7 files changed

+105
-29
lines changed

picasso/src/main/java/com/squareup/picasso/BitmapHunter.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -463,12 +463,15 @@ static Bitmap transformResult(Request data, Bitmap result, int exifRotation) {
463463
float heightRatio = targetHeight / (float) inHeight;
464464
float scale = widthRatio < heightRatio ? widthRatio : heightRatio;
465465
matrix.preScale(scale, scale);
466-
} else if (targetWidth != 0 && targetHeight != 0 //
466+
} else if ((targetWidth != 0 || targetHeight != 0) //
467467
&& (targetWidth != inWidth || targetHeight != inHeight)) {
468468
// If an explicit target size has been specified and they do not match the results bounds,
469469
// pre-scale the existing matrix appropriately.
470-
float sx = targetWidth / (float) inWidth;
471-
float sy = targetHeight / (float) inHeight;
470+
// Keep aspect ratio if one dimension is set to 0.
471+
float sx = targetWidth != 0 ? targetWidth / (float) inWidth
472+
: targetHeight / (float) inHeight;
473+
float sy = targetHeight != 0 ? targetHeight / (float) inHeight
474+
: targetWidth / (float) inWidth;
472475
matrix.preScale(sx, sy);
473476
}
474477
}

picasso/src/main/java/com/squareup/picasso/Request.java

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -157,15 +157,15 @@ String getName() {
157157
}
158158

159159
public boolean hasSize() {
160-
return targetWidth != 0;
160+
return targetWidth != 0 || targetHeight != 0;
161161
}
162162

163163
boolean needsTransformation() {
164164
return needsMatrixTransform() || hasCustomTransformations();
165165
}
166166

167167
boolean needsMatrixTransform() {
168-
return targetWidth != 0 || rotationDegrees != 0;
168+
return hasSize() || rotationDegrees != 0;
169169
}
170170

171171
boolean hasCustomTransformations() {
@@ -230,7 +230,7 @@ boolean hasImage() {
230230
}
231231

232232
boolean hasSize() {
233-
return targetWidth != 0;
233+
return targetWidth != 0 || targetHeight != 0;
234234
}
235235

236236
boolean hasPriority() {
@@ -265,13 +265,19 @@ public Builder setResourceId(int resourceId) {
265265
return this;
266266
}
267267

268-
/** Resize the image to the specified size in pixels. */
268+
/**
269+
* Resize the image to the specified size in pixels.
270+
* Use 0 as desired dimension to resize keeping aspect ratio.
271+
*/
269272
public Builder resize(int targetWidth, int targetHeight) {
270-
if (targetWidth <= 0) {
271-
throw new IllegalArgumentException("Width must be positive number.");
273+
if (targetWidth < 0) {
274+
throw new IllegalArgumentException("Width must be positive number or 0.");
275+
}
276+
if (targetHeight < 0) {
277+
throw new IllegalArgumentException("Height must be positive number or 0.");
272278
}
273-
if (targetHeight <= 0) {
274-
throw new IllegalArgumentException("Height must be positive number.");
279+
if (targetHeight == 0 && targetWidth == 0) {
280+
throw new IllegalArgumentException("At least one dimension has to be positive number.");
275281
}
276282
this.targetWidth = targetWidth;
277283
this.targetHeight = targetHeight;
@@ -390,11 +396,13 @@ public Request build() {
390396
if (centerInside && centerCrop) {
391397
throw new IllegalStateException("Center crop and center inside can not be used together.");
392398
}
393-
if (centerCrop && targetWidth == 0) {
394-
throw new IllegalStateException("Center crop requires calling resize.");
399+
if (centerCrop && (targetWidth == 0 || targetHeight == 0)) {
400+
throw new IllegalStateException(
401+
"Center crop requires calling resize with positive width and height.");
395402
}
396-
if (centerInside && targetWidth == 0) {
397-
throw new IllegalStateException("Center inside requires calling resize.");
403+
if (centerInside && (targetWidth == 0 || targetHeight == 0)) {
404+
throw new IllegalStateException(
405+
"Center inside requires calling resize with positive width and height.");
398406
}
399407
if (priority == null) {
400408
priority = Priority.NORMAL;

picasso/src/main/java/com/squareup/picasso/RequestHandler.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,19 @@ static void calculateInSampleSize(int reqWidth, int reqHeight, int width, int he
145145
BitmapFactory.Options options, Request request) {
146146
int sampleSize = 1;
147147
if (height > reqHeight || width > reqWidth) {
148-
final int heightRatio = (int) Math.floor((float) height / (float) reqHeight);
149-
final int widthRatio = (int) Math.floor((float) width / (float) reqWidth);
150-
sampleSize = request.centerInside
151-
? Math.max(heightRatio, widthRatio)
152-
: Math.min(heightRatio, widthRatio);
148+
final int heightRatio;
149+
final int widthRatio;
150+
if (reqHeight == 0) {
151+
sampleSize = (int) Math.floor((float) width / (float) reqWidth);
152+
} else if (reqWidth == 0) {
153+
sampleSize = (int) Math.floor((float) height / (float) reqHeight);
154+
} else {
155+
heightRatio = (int) Math.floor((float) height / (float) reqHeight);
156+
widthRatio = (int) Math.floor((float) width / (float) reqWidth);
157+
sampleSize = request.centerInside
158+
? Math.max(heightRatio, widthRatio)
159+
: Math.min(heightRatio, widthRatio);
160+
}
153161
}
154162
options.inSampleSize = sampleSize;
155163
options.inJustDecodeBounds = false;

picasso/src/main/java/com/squareup/picasso/Utils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ static String createKey(Request data, StringBuilder builder) {
181181
}
182182
builder.append('\n');
183183
}
184-
if (data.targetWidth != 0) {
184+
if (data.hasSize()) {
185185
builder.append("resize:").append(data.targetWidth).append('x').append(data.targetHeight);
186186
builder.append('\n');
187187
}

picasso/src/test/java/com/squareup/picasso/BitmapHunterTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,30 @@ public class BitmapHunterTest {
405405
assertThat(shadowMatrix.getPreOperations()).containsOnly("rotate 90.0");
406406
}
407407

408+
@Test public void keepsAspectRationWhileResizingWhenDesiredWidthIs0() throws Exception {
409+
Request request = new Request.Builder(URI_1).resize(20, 0).build();
410+
Bitmap source = Bitmap.createBitmap(40, 20, ARGB_8888);
411+
412+
Bitmap result = transformResult(request, source, 0);
413+
414+
ShadowBitmap shadowBitmap = shadowOf(result);
415+
Matrix matrix = shadowBitmap.getCreatedFromMatrix();
416+
ShadowMatrix shadowMatrix = shadowOf(matrix);
417+
assertThat(shadowMatrix.getPreOperations()).containsOnly("scale 0.5 0.5");
418+
}
419+
420+
@Test public void keepsAspectRationWhileResizingWhenDesiredHeighIs0() throws Exception {
421+
Request request = new Request.Builder(URI_1).resize(0, 10).build();
422+
Bitmap source = Bitmap.createBitmap(40, 20, ARGB_8888);
423+
424+
Bitmap result = transformResult(request, source, 0);
425+
426+
ShadowBitmap shadowBitmap = shadowOf(result);
427+
Matrix matrix = shadowBitmap.getCreatedFromMatrix();
428+
ShadowMatrix shadowMatrix = shadowOf(matrix);
429+
assertThat(shadowMatrix.getPreOperations()).containsOnly("scale 0.5 0.5");
430+
}
431+
408432
@Test public void exifRotationWithManualRotation() throws Exception {
409433
Bitmap source = Bitmap.createBitmap(10, 10, ARGB_8888);
410434
Request data = new Request.Builder(URI_1).rotate(-45).build();

picasso/src/test/java/com/squareup/picasso/RequestCreatorTest.java

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,31 @@ public void intoRemoteViewsNotificationWithFitThrows() {
514514
}
515515
}
516516

517-
@Test public void appWidgetActionWithDefaultPriority() {
517+
@Test
518+
public void intoTargetResizeWith0WithCenterInsideOrCenterCropThrows() {
519+
try {
520+
new RequestCreator(picasso, URI_1, 0).resize(0, 10).centerInside().into(mockTarget());
521+
fail("Center inside with unknown width should throw exception.");
522+
} catch (IllegalStateException ignored) {
523+
}
524+
try {
525+
new RequestCreator(picasso, URI_1, 0).resize(10, 0).centerInside().into(mockTarget());
526+
fail("Center inside with unknown height should throw exception.");
527+
} catch (IllegalStateException ignored) {
528+
}
529+
try {
530+
new RequestCreator(picasso, URI_1, 0).resize(0, 10).centerCrop().into(mockTarget());
531+
fail("Center inside with unknown width should throw exception.");
532+
} catch (IllegalStateException ignored) {
533+
}
534+
try {
535+
new RequestCreator(picasso, URI_1, 0).resize(10, 0).centerCrop().into(mockTarget());
536+
fail("Center inside with unknown height should throw exception.");
537+
} catch (IllegalStateException ignored) {
538+
}
539+
}
540+
541+
@Test public void appWidgetActionWithDefaultPriority() throws Exception {
518542
new RequestCreator(picasso, URI_1, 0).into(mockRemoteViews(), 0, new int[] { 1, 2, 3 });
519543
verify(picasso).enqueueAndSubmit(actionCaptor.capture());
520544
assertThat(actionCaptor.getValue().getPriority()).isEqualTo(NORMAL);
@@ -578,13 +602,8 @@ public void intoRemoteViewsNotificationWithFitThrows() {
578602
} catch (IllegalArgumentException ignored) {
579603
}
580604
try {
581-
new RequestCreator().resize(0, 10);
582-
fail("Zero width should throw exception.");
583-
} catch (IllegalArgumentException ignored) {
584-
}
585-
try {
586-
new RequestCreator().resize(10, 0);
587-
fail("Zero height should throw exception.");
605+
new RequestCreator().resize(0, 0);
606+
fail("Zero dimensions should throw exception.");
588607
} catch (IllegalArgumentException ignored) {
589608
}
590609
}

picasso/src/test/java/com/squareup/picasso/RequestHandlerTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,20 @@ public class RequestHandlerTest {
7373
assertThat(options.inSampleSize).isEqualTo(4);
7474
}
7575

76+
@Test public void calculateInSampleSizeKeepAspectRatioWithWidth() {
77+
final BitmapFactory.Options options = new BitmapFactory.Options();
78+
Request data = new Request.Builder(URI_1).resize(400, 0).build();
79+
calculateInSampleSize(data.targetWidth, data.targetHeight, 800, 200, options, data);
80+
assertThat(options.inSampleSize).isEqualTo(2);
81+
}
82+
83+
@Test public void calculateInSampleSizeKeepAspectRatioWithHeight() {
84+
final BitmapFactory.Options options = new BitmapFactory.Options();
85+
Request data = new Request.Builder(URI_1).resize(0, 100).build();
86+
calculateInSampleSize(data.targetWidth, data.targetHeight, 800, 200, options, data);
87+
assertThat(options.inSampleSize).isEqualTo(2);
88+
}
89+
7690
@Test public void nullBitmapOptionsIfNoResizing() {
7791
// No resize must return no bitmap options
7892
final Request noResize = new Request.Builder(URI_1).build();

0 commit comments

Comments
 (0)