Skip to content

Commit 74ac63f

Browse files
committed
Possible fix for square#769
When Center Crop is used, a single scale factor is calculated to transform the input image to a target image size. This does not work for all input cases. I'm not sure if this is the best solution but hope this at least starts a discussion. The summary of the problem: integers multiplied by a transformation matrix of floats cannot always create the requested targetSize. A single scale factor cannot be used for both X and Y because the input sizes are integers. Test included.
1 parent 4f527b7 commit 74ac63f

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -451,19 +451,21 @@ static Bitmap transformResult(Request data, Bitmap result, int exifRotation) {
451451
if (data.centerCrop) {
452452
float widthRatio = targetWidth / (float) inWidth;
453453
float heightRatio = targetHeight / (float) inHeight;
454-
float scale;
454+
float scaleX, scaleY;
455455
if (widthRatio > heightRatio) {
456-
scale = widthRatio;
457456
int newSize = (int) Math.ceil(inHeight * (heightRatio / widthRatio));
458457
drawY = (inHeight - newSize) / 2;
459458
drawHeight = newSize;
459+
scaleX = widthRatio;
460+
scaleY = targetHeight / (float) drawHeight;
460461
} else {
461-
scale = heightRatio;
462462
int newSize = (int) Math.ceil(inWidth * (widthRatio / heightRatio));
463463
drawX = (inWidth - newSize) / 2;
464464
drawWidth = newSize;
465+
scaleX = targetWidth / (float) drawWidth;
466+
scaleY = heightRatio;
465467
}
466-
matrix.preScale(scale, scale);
468+
matrix.preScale(scaleX, scaleY);
467469
} else if (data.centerInside) {
468470
float widthRatio = targetWidth / (float) inWidth;
469471
float heightRatio = targetHeight / (float) inHeight;

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,27 @@ public class BitmapHunterTest {
431431
assertThat(shadowMatrix.getPreOperations()).containsOnly("scale 0.5 0.5");
432432
}
433433

434+
@Test public void centerCropResultMatchesTargetSize() throws Exception {
435+
Request request = new Request.Builder(URI_1).resize(1080, 642).centerCrop().build();
436+
Bitmap source = Bitmap.createBitmap(640, 640, ARGB_8888);
437+
438+
Bitmap result = transformResult(request, source, 0);
439+
440+
ShadowBitmap shadowBitmap = shadowOf(result);
441+
Matrix matrix = shadowBitmap.getCreatedFromMatrix();
442+
ShadowMatrix shadowMatrix = shadowOf(matrix);
443+
String scalePreOperation = shadowMatrix.getPreOperations().get(0);
444+
445+
assertThat(scalePreOperation).startsWith("scale ");
446+
float scaleX = Float.valueOf(scalePreOperation.split(" ")[1]);
447+
float scaleY = Float.valueOf(scalePreOperation.split(" ")[2]);
448+
449+
int transformedWidth = Math.round(result.getWidth() * scaleX);
450+
int transformedHeight = Math.round(result.getHeight() * scaleY);
451+
assertThat(transformedWidth).isEqualTo(1080);
452+
assertThat(transformedHeight).isEqualTo(642);
453+
}
454+
434455
@Test public void exifRotationWithManualRotation() throws Exception {
435456
Bitmap source = Bitmap.createBitmap(10, 10, ARGB_8888);
436457
Request data = new Request.Builder(URI_1).rotate(-45).build();

0 commit comments

Comments
 (0)