Skip to content

Commit

Permalink
fix for issue bumptech#738 Some images simply do not download (Black …
Browse files Browse the repository at this point in the history
…image) - Android
  • Loading branch information
Matthijs Mullender committed Nov 20, 2015
1 parent 4f159aa commit def92c7
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -196,12 +196,12 @@ private Bitmap decodeFromWrappedStreams(InputStream is,
}

// Visible for testing.
static void calculateScaling(DownsampleStrategy downsampleStrategy, int degreesToRotate,
static float calculateScaling(DownsampleStrategy downsampleStrategy, int degreesToRotate,
int sourceWidth, int sourceHeight, int requestedWidth, int requestedHeight,
BitmapFactory.Options options) {
// We can't downsample source content if we can't determine its dimensions.
if (sourceWidth <= 0 || sourceHeight <= 0) {
return;
return 1;
}

int targetHeight = requestedHeight == Target.SIZE_ORIGINAL ? sourceHeight : requestedHeight;
Expand Down Expand Up @@ -248,17 +248,6 @@ static void calculateScaling(DownsampleStrategy downsampleStrategy, int degreesT
float adjustedScaleFactor = powerOfTwoSampleSize * exactScaleFactor;

options.inSampleSize = powerOfTwoSampleSize;
// Density scaling is only supported if inBitmap is null prior to KitKat. Avoid setting
// densities here so we calculate the final Bitmap size correctly.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
options.inTargetDensity = (int) (1000 * adjustedScaleFactor + 0.5f);
options.inDensity = 1000;
}
if (isScaling(options)) {
options.inScaled = true;
} else {
options.inDensity = options.inTargetDensity = 0;
}

if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Calculate scaling"
Expand All @@ -270,6 +259,7 @@ static void calculateScaling(DownsampleStrategy downsampleStrategy, int degreesT
+ ", target density: " + options.inTargetDensity
+ ", density: " + options.inDensity);
}
return adjustedScaleFactor;
}

private int getOrientation(InputStream is) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public final class TransformationUtils {
private static final int CIRCLE_CROP_PAINT_FLAGS = PAINT_FLAGS | Paint.ANTI_ALIAS_FLAG;
private static final Paint CIRCLE_CROP_SHAPE_PAINT = new Paint(CIRCLE_CROP_PAINT_FLAGS);
private static final Paint CIRCLE_CROP_BITMAP_PAINT;
private static final Object LOCK = new Object();

static {
CIRCLE_CROP_BITMAP_PAINT = new Paint(CIRCLE_CROP_PAINT_FLAGS);
CIRCLE_CROP_BITMAP_PAINT.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
Expand All @@ -45,7 +47,7 @@ private TransformationUtils() {
* Bitmap with the given dimensions is passed in as well.
*
* @param pool The BitmapPool to obtain a bitmap from.
* @param inBitmap The Bitmap to resize.
* @param inBitmap The Bitmap to resize.
* @param width The width in pixels of the final Bitmap.
* @param height The height in pixels of the final Bitmap.
* @return The resized Bitmap (will be recycled if recycled is not null).
Expand Down Expand Up @@ -74,20 +76,22 @@ public static Bitmap centerCrop(@NonNull BitmapPool pool, @NonNull Bitmap inBitm
// We don't add or remove alpha, so keep the alpha setting of the Bitmap we were given.
TransformationUtils.setAlpha(inBitmap, result);

Canvas canvas = new Canvas(result);
canvas.drawBitmap(inBitmap, m, DEFAULT_PAINT);
clear(canvas);
synchronized (LOCK) {
Canvas canvas = new Canvas(result);
canvas.drawBitmap(inBitmap, m, DEFAULT_PAINT);
clear(canvas);
}
return result;
}

/**
* An expensive operation to resize the given Bitmap down so that it fits within the given
* dimensions maintain the original proportions.
*
* @param pool The BitmapPool obtain a bitmap from.
* @param inBitmap The Bitmap to shrink.
* @param width The width in pixels the final image will fit within.
* @param height The height in pixels the final image will fit within.
* @param pool The BitmapPool obtain a bitmap from.
* @param inBitmap The Bitmap to shrink.
* @param width The width in pixels the final image will fit within.
* @param height The height in pixels the final image will fit within.
* @return A new Bitmap shrunk to fit within the given dimensions, or toFit if toFit's width or
* height matches the given dimensions and toFit fits within the given dimensions
*/
Expand Down Expand Up @@ -129,11 +133,13 @@ public static Bitmap fitCenter(@NonNull BitmapPool pool, @NonNull Bitmap inBitma
Log.v(TAG, "minPct: " + minPercentage);
}

Canvas canvas = new Canvas(toReuse);
Matrix matrix = new Matrix();
matrix.setScale(minPercentage, minPercentage);
canvas.drawBitmap(inBitmap, matrix, DEFAULT_PAINT);
clear(canvas);
synchronized (LOCK) {
Canvas canvas = new Canvas(toReuse);
Matrix matrix = new Matrix();
matrix.setScale(minPercentage, minPercentage);
canvas.drawBitmap(inBitmap, matrix, DEFAULT_PAINT);
clear(canvas);
}

return toReuse;
}
Expand All @@ -143,9 +149,9 @@ public static Bitmap fitCenter(@NonNull BitmapPool pool, @NonNull Bitmap inBitma
* transform. This keeps {@link android.graphics.Bitmap#hasAlpha()}} consistent before and after
* the transformation for transformations that don't add or remove transparent pixels.
*
* @param inBitmap The {@link android.graphics.Bitmap} that will be transformed.
* @param outBitmap The {@link android.graphics.Bitmap} that will be returned from the
* transformation.
* @param inBitmap The {@link android.graphics.Bitmap} that will be transformed.
* @param outBitmap The {@link android.graphics.Bitmap} that will be returned from the
* transformation.
*/
public static void setAlpha(Bitmap inBitmap, Bitmap outBitmap) {
setAlphaIfAvailable(outBitmap, inBitmap.hasAlpha());
Expand Down Expand Up @@ -240,21 +246,22 @@ public static Bitmap rotateImageExif(@NonNull BitmapPool pool, @NonNull Bitmap i

matrix.postTranslate(-newRect.left, -newRect.top);

final Canvas canvas = new Canvas(result);
canvas.drawBitmap(inBitmap, matrix, DEFAULT_PAINT);
clear(canvas);

synchronized (LOCK) {
final Canvas canvas = new Canvas(result);
canvas.drawBitmap(inBitmap, matrix, DEFAULT_PAINT);
clear(canvas);
}
return result;
}

/**
* Crop the image to a circle and resize to the specified width/height. The circle crop will
* have the same width and height equal to the min-edge of the result image.
* Crop the image to a circle and resize to the specified width/height. The circle crop will have
* the same width and height equal to the min-edge of the result image.
*
* @param pool The BitmapPool obtain a bitmap from.
* @param pool The BitmapPool obtain a bitmap from.
* @param inBitmap The Bitmap to resize.
* @param destWidth The width in pixels of the final Bitmap.
* @param destHeight The height in pixels of the final Bitmap.
* @param destWidth The width in pixels of the final Bitmap.
* @param destHeight The height in pixels of the final Bitmap.
* @return The resized Bitmap (will be recycled if recycled is not null).
*/
public static Bitmap circleCrop(@NonNull BitmapPool pool, @NonNull Bitmap inBitmap,
Expand All @@ -275,15 +282,18 @@ public static Bitmap circleCrop(@NonNull BitmapPool pool, @NonNull Bitmap inBitm

Bitmap result = pool.get(destWidth, destHeight, getSafeConfig(toTransform));
setAlphaIfAvailable(result, true /*hasAlpha*/);
Canvas canvas = new Canvas(result);

// Draw a circle
canvas.drawCircle(destRect.left + radius, destRect.top + radius, radius,
CIRCLE_CROP_SHAPE_PAINT);
synchronized (LOCK) {
Canvas canvas = new Canvas(result);

// Draw a circle
canvas.drawCircle(destRect.left + radius, destRect.top + radius, radius,
CIRCLE_CROP_SHAPE_PAINT);

// Draw the bitmap in the circle
canvas.drawBitmap(toTransform, srcRect, destRect, CIRCLE_CROP_BITMAP_PAINT);
clear(canvas);
// Draw the bitmap in the circle
canvas.drawBitmap(toTransform, srcRect, destRect, CIRCLE_CROP_BITMAP_PAINT);
clear(canvas);
}

if (!toTransform.equals(inBitmap)) {
pool.put(toTransform);
Expand All @@ -310,9 +320,9 @@ private static Bitmap getAlphaSafeBitmap(@NonNull BitmapPool pool,
/**
* Creates a bitmap from a source bitmap and rounds the corners.
*
* @param inBitmap the source bitmap to use as a basis for the created bitmap.
* @param width the width of the generated bitmap.
* @param height the height of the generated bitmap.
* @param inBitmap the source bitmap to use as a basis for the created bitmap.
* @param width the width of the generated bitmap.
* @param height the height of the generated bitmap.
* @param roundingRadius the corner radius to be applied (in device-specific pixels).
* @return a {@link Bitmap} similar to inBitmap but with rounded corners.
* @throws IllegalArgumentException if roundingRadius, width or height is 0 or less.
Expand All @@ -335,10 +345,13 @@ public static Bitmap roundedCorners(@NonNull BitmapPool pool, @NonNull Bitmap in
paint.setAntiAlias(true);
paint.setShader(shader);
RectF rect = new RectF(0, 0, result.getWidth(), result.getHeight());
Canvas canvas = new Canvas(result);
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
canvas.drawRoundRect(rect, roundingRadius, roundingRadius, paint);
clear(canvas);

synchronized (LOCK) {
Canvas canvas = new Canvas(result);
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
canvas.drawRoundRect(rect, roundingRadius, roundingRadius, paint);
clear(canvas);
}

if (!toTransform.equals(inBitmap)) {
pool.put(toTransform);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,19 +155,19 @@ public void testCalculateScaling_withNone() {
private static void runScaleTest(int sourceWidth, int sourceHeight, int targetWidth,
int targetHeight, DownsampleStrategy strategy, int expectedWidth, int expectedHeight) {
BitmapFactory.Options options = new BitmapFactory.Options();
Downsampler.calculateScaling(strategy, 0, sourceWidth, sourceHeight, targetWidth, targetHeight,
options);
assertSize(sourceWidth, sourceHeight, expectedWidth, expectedHeight, options);
float adjustedScaleFactor = Downsampler.calculateScaling(strategy, 0, sourceWidth, sourceHeight,
targetWidth, targetHeight, options);
assertSize(sourceWidth, sourceHeight, expectedWidth, expectedHeight, options,
adjustedScaleFactor);
}

private static void assertSize(int sourceWidth, int sourceHeight, int expectedWidth,
int expectedHeight, BitmapFactory.Options options) {
int expectedHeight, BitmapFactory.Options options, float adjustedScaleFactor) {
float sampleSize = Math.max(1, options.inSampleSize);
int downsampledWidth = (int) ((sourceWidth / sampleSize) + 0.5f);
int downsampledHeight = (int) ((sourceHeight / sampleSize) + 0.5f);

float scaleFactor = options.inScaled && options.inTargetDensity > 0 && options.inDensity > 0
? options.inTargetDensity / (float) options.inDensity : 1f;
float scaleFactor = adjustedScaleFactor;
int scaledWidth = (int) Math.ceil(downsampledWidth * scaleFactor);
int scaledHeight = (int) Math.ceil(downsampledHeight * scaleFactor);

Expand Down

0 comments on commit def92c7

Please sign in to comment.