Skip to content

Commit 7663c21

Browse files
committed
Add support for passing through Bitmaps and Drawables.
1 parent f7a939e commit 7663c21

File tree

7 files changed

+207
-39
lines changed

7 files changed

+207
-39
lines changed

library/src/main/java/com/bumptech/glide/Glide.java

+7
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,11 @@
5454
import com.bumptech.glide.load.resource.bitmap.Downsampler;
5555
import com.bumptech.glide.load.resource.bitmap.ResourceBitmapDecoder;
5656
import com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder;
57+
import com.bumptech.glide.load.resource.bitmap.UnitBitmapDecoder;
5758
import com.bumptech.glide.load.resource.bitmap.VideoBitmapDecoder;
5859
import com.bumptech.glide.load.resource.bytes.ByteBufferRewinder;
5960
import com.bumptech.glide.load.resource.drawable.ResourceDrawableDecoder;
61+
import com.bumptech.glide.load.resource.drawable.UnitDrawableDecoder;
6062
import com.bumptech.glide.load.resource.file.FileDecoder;
6163
import com.bumptech.glide.load.resource.gif.ByteBufferGifDecoder;
6264
import com.bumptech.glide.load.resource.gif.GifDrawable;
@@ -321,6 +323,9 @@ private static GeneratedAppGlideModule getAnnotationGeneratedGlideModules() {
321323
.append(Registry.BUCKET_BITMAP, InputStream.class, Bitmap.class, streamBitmapDecoder)
322324
.append(
323325
Registry.BUCKET_BITMAP, ParcelFileDescriptor.class, Bitmap.class, videoBitmapDecoder)
326+
.append(
327+
Registry.BUCKET_BITMAP, Bitmap.class, Bitmap.class, new UnitBitmapDecoder(bitmapPool))
328+
.append(Bitmap.class, Bitmap.class, UnitModelLoader.Factory.<Bitmap>getInstance())
324329
.append(Bitmap.class, bitmapEncoder)
325330
/* BitmapDrawables */
326331
.append(
@@ -406,6 +411,8 @@ Uri.class, Bitmap.class, new ResourceBitmapDecoder(resourceDrawableDecoder, bitm
406411
.append(byte[].class, ByteBuffer.class, new ByteArrayLoader.ByteBufferFactory())
407412
.append(byte[].class, InputStream.class, new ByteArrayLoader.StreamFactory())
408413
.append(Uri.class, Uri.class, UnitModelLoader.Factory.<Uri>getInstance())
414+
.append(Drawable.class, Drawable.class, UnitModelLoader.Factory.<Drawable>getInstance())
415+
.append(Drawable.class, Drawable.class, new UnitDrawableDecoder(bitmapPool))
409416
/* Transcoders */
410417
.register(
411418
Bitmap.class,

library/src/main/java/com/bumptech/glide/RequestBuilder.java

+55-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package com.bumptech.glide;
22

3+
import static com.bumptech.glide.request.RequestOptions.diskCacheStrategyOf;
34
import static com.bumptech.glide.request.RequestOptions.signatureOf;
45

56
import android.content.Context;
7+
import android.graphics.Bitmap;
8+
import android.graphics.drawable.Drawable;
69
import android.net.Uri;
710
import android.support.annotation.CheckResult;
811
import android.support.annotation.DrawableRes;
@@ -317,7 +320,58 @@ private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
317320
}
318321

319322
/**
320-
* Returns a request builder to load the given {@link java.lang.String}. signature.
323+
* Returns a request builder to load the given {@link Bitmap}.
324+
*
325+
* <p>{@link Bitmap}s provided to this method become owned by Glide. The {@link Bitmap} may be
326+
* recycled or re-used at any time. If you do not own the Bitmap or you need to continue to use
327+
* the {@link Bitmap} after passing it in to Glide, consider passing a copy of the {@link Bitmap}
328+
* to Glide instead. It's almost always better to allow Glide to load {@link Bitmap}s than
329+
* pass {@link Bitmap}s into Glide. If you have a custom way to obtain {@link Bitmap}s that is
330+
* not supported by Glide, consider registering a custom
331+
* {@link com.bumptech.glide.load.model.ModelLoader} or
332+
* {@link com.bumptech.glide.load.ResourceDecoder} instead.
333+
*
334+
* <p>The {@link DiskCacheStrategy} is set to {@link DiskCacheStrategy#NONE}. Using other
335+
* strategies may result in undefined behavior.
336+
*
337+
* <p>In memory caching relies on Object equality. The contents of the {@link Bitmap}s are not
338+
* compared.
339+
*
340+
* @see #load(Object)
341+
*/
342+
@CheckResult
343+
public RequestBuilder<TranscodeType> load(@Nullable Bitmap bitmap) {
344+
return loadGeneric(bitmap)
345+
.apply(diskCacheStrategyOf(DiskCacheStrategy.NONE));
346+
}
347+
348+
/**
349+
* Returns a request builder to load the given {@link Drawable}.
350+
*
351+
* <p>{@link Drawable}s provided to this method become owned by Glide. They or {@link Bitmap}s
352+
* they contain may be recycled or re-used at any time. If you do not own the {@link Drawable},
353+
* do not pass it in to Glide. It's almost always better to allow Glide to load {@link Bitmap}s
354+
* than pass {@link Bitmap}s into Glide. If you have a custom way to obtain {@link Bitmap}s that
355+
* is not supported by Glide, consider registering a custom
356+
* {@link com.bumptech.glide.load.model.ModelLoader} or
357+
* {@link com.bumptech.glide.load.ResourceDecoder} instead.
358+
*
359+
* <p>The {@link DiskCacheStrategy} is set to {@link DiskCacheStrategy#NONE}. Using other
360+
* strategies may result in undefined behavior.
361+
*
362+
* <p>In memory caching relies on Object equality. The contents of the {@link Drawable}s are not
363+
* compared.
364+
*
365+
* @see #load(Object)
366+
*/
367+
@CheckResult
368+
public RequestBuilder<TranscodeType> load(@Nullable Drawable drawable) {
369+
return loadGeneric(drawable)
370+
.apply(diskCacheStrategyOf(DiskCacheStrategy.NONE));
371+
}
372+
373+
/**
374+
* Returns a request builder to load the given {@link java.lang.String}.
321375
*
322376
* <p> Note - this method caches data using only the given String as the cache key. If the data is
323377
* a Uri outside of your control, or you otherwise expect the data represented by the given String
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.bumptech.glide.load.resource.bitmap;
2+
3+
import android.graphics.Bitmap;
4+
import android.support.annotation.Nullable;
5+
import com.bumptech.glide.load.Options;
6+
import com.bumptech.glide.load.ResourceDecoder;
7+
import com.bumptech.glide.load.engine.Resource;
8+
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
9+
import java.io.IOException;
10+
11+
public final class UnitBitmapDecoder implements ResourceDecoder<Bitmap, Bitmap> {
12+
13+
private final BitmapPool bitmapPool;
14+
15+
public UnitBitmapDecoder(BitmapPool bitmapPool) {
16+
this.bitmapPool = bitmapPool;
17+
}
18+
19+
@Override
20+
public boolean handles(Bitmap source, Options options) throws IOException {
21+
return true;
22+
}
23+
24+
@Nullable
25+
@Override
26+
public Resource<Bitmap> decode(Bitmap source, int width, int height, Options options)
27+
throws IOException {
28+
return new BitmapResource(source, bitmapPool);
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.bumptech.glide.load.resource.drawable;
2+
3+
import android.graphics.drawable.BitmapDrawable;
4+
import android.graphics.drawable.Drawable;
5+
import com.bumptech.glide.load.engine.Resource;
6+
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
7+
import com.bumptech.glide.load.resource.bitmap.BitmapDrawableResource;
8+
9+
/**
10+
* Handles generic {@link Drawable} types where we may be uncertain of their size or type.
11+
*/
12+
final class DrawableResourceImpl extends DrawableResource<Drawable> {
13+
14+
@SuppressWarnings("unchecked")
15+
public static Resource<Drawable> newInstance(Drawable drawable, BitmapPool bitmapPool) {
16+
if (drawable instanceof BitmapDrawable) {
17+
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
18+
return (Resource<Drawable>) (Resource<? extends Drawable>)
19+
new BitmapDrawableResource(bitmapDrawable, bitmapPool);
20+
}
21+
return new DrawableResourceImpl(drawable);
22+
}
23+
24+
private DrawableResourceImpl(Drawable drawable) {
25+
super(drawable);
26+
}
27+
28+
@SuppressWarnings("unchecked")
29+
@Override
30+
public Class<Drawable> getResourceClass() {
31+
return (Class<Drawable>) drawable.getClass();
32+
}
33+
34+
@Override
35+
public int getSize() {
36+
// 4 bytes per pixel for ARGB_8888 Bitmaps is something of a reasonable approximation. If
37+
// there are no intrinsic bounds, we can fall back just to 1.
38+
return Math.max(1, drawable.getIntrinsicWidth() * drawable.getIntrinsicHeight() * 4);
39+
}
40+
41+
@Override
42+
public void recycle() {
43+
// Do nothing.
44+
}
45+
}

library/src/main/java/com/bumptech/glide/load/resource/drawable/ResourceDrawableDecoder.java

+1-38
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import android.content.ContentResolver;
44
import android.content.Context;
55
import android.content.pm.PackageManager.NameNotFoundException;
6-
import android.graphics.drawable.BitmapDrawable;
76
import android.graphics.drawable.Drawable;
87
import android.net.Uri;
98
import android.support.annotation.DrawableRes;
@@ -12,7 +11,6 @@
1211
import com.bumptech.glide.load.ResourceDecoder;
1312
import com.bumptech.glide.load.engine.Resource;
1413
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
15-
import com.bumptech.glide.load.resource.bitmap.BitmapDrawableResource;
1614
import java.io.IOException;
1715
import java.util.List;
1816

@@ -56,17 +54,7 @@ public Resource<Drawable> decode(Uri source, int width, int height, Options opti
5654
? context : getContextForPackage(source, packageName);
5755
// We can't get a theme from another application.
5856
Drawable drawable = DrawableDecoderCompat.getDrawable(toUse, resId);
59-
return getDrawableResource(drawable);
60-
}
61-
62-
@SuppressWarnings("unchecked")
63-
private Resource<Drawable> getDrawableResource(Drawable drawable) {
64-
if (drawable instanceof BitmapDrawable) {
65-
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
66-
return (Resource<Drawable>) (Resource<? extends Drawable>)
67-
new BitmapDrawableResource(bitmapDrawable, bitmapPool);
68-
}
69-
return new InternalDrawableResource(drawable);
57+
return DrawableResourceImpl.newInstance(drawable, bitmapPool);
7058
}
7159

7260
@NonNull
@@ -103,29 +91,4 @@ private int loadResourceIdFromUri(Uri source) {
10391
}
10492
return result;
10593
}
106-
107-
private static final class InternalDrawableResource extends DrawableResource<Drawable> {
108-
109-
InternalDrawableResource(Drawable drawable) {
110-
super(drawable);
111-
}
112-
113-
@SuppressWarnings("unchecked")
114-
@Override
115-
public Class<Drawable> getResourceClass() {
116-
return (Class<Drawable>) drawable.getClass();
117-
}
118-
119-
@Override
120-
public int getSize() {
121-
// 4 bytes per pixel for ARGB_8888 Bitmaps is something of a reasonable approximation. If
122-
// there are no intrinsic bounds, we can fall back just to 1.
123-
return Math.max(1, drawable.getIntrinsicWidth() * drawable.getIntrinsicHeight() * 4);
124-
}
125-
126-
@Override
127-
public void recycle() {
128-
// Do nothing.
129-
}
130-
}
13194
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.bumptech.glide.load.resource.drawable;
2+
3+
import android.graphics.drawable.Drawable;
4+
import android.support.annotation.Nullable;
5+
import com.bumptech.glide.load.Options;
6+
import com.bumptech.glide.load.ResourceDecoder;
7+
import com.bumptech.glide.load.engine.Resource;
8+
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
9+
import java.io.IOException;
10+
11+
/**
12+
* Passes through a {@link Drawable} as a {@link Drawable} based {@link Resource}.
13+
*/
14+
public class UnitDrawableDecoder implements ResourceDecoder<Drawable, Drawable> {
15+
private final BitmapPool bitmapPool;
16+
17+
public UnitDrawableDecoder(BitmapPool bitmapPool) {
18+
this.bitmapPool = bitmapPool;
19+
}
20+
21+
@Override
22+
public boolean handles(Drawable source, Options options) throws IOException {
23+
return true;
24+
}
25+
26+
@Nullable
27+
@Override
28+
public Resource<Drawable> decode(Drawable source, int width, int height, Options options)
29+
throws IOException {
30+
return DrawableResourceImpl.newInstance(source, bitmapPool);
31+
}
32+
}

library/src/test/java/com/bumptech/glide/GlideTest.java

+37
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import static com.bumptech.glide.request.RequestOptions.decodeTypeOf;
44
import static com.bumptech.glide.request.RequestOptions.errorOf;
55
import static com.bumptech.glide.request.RequestOptions.placeholderOf;
6+
import static com.google.common.truth.Truth.assertThat;
67
import static org.junit.Assert.assertEquals;
78
import static org.junit.Assert.assertNotNull;
9+
import static org.mockito.Matchers.any;
810
import static org.mockito.Matchers.anyInt;
911
import static org.mockito.Matchers.eq;
1012
import static org.mockito.Matchers.isA;
@@ -70,6 +72,7 @@
7072
import org.junit.Before;
7173
import org.junit.Test;
7274
import org.junit.runner.RunWith;
75+
import org.mockito.ArgumentCaptor;
7376
import org.mockito.invocation.InvocationOnMock;
7477
import org.mockito.stubbing.Answer;
7578
import org.robolectric.RobolectricTestRunner;
@@ -554,6 +557,40 @@ public void testNullModelPrefersErrorDrawable() {
554557
verify(target).onLoadFailed(eq(error));
555558
}
556559

560+
@Test
561+
public void testLoadBitmap_asBitmap() {
562+
Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
563+
requestManager
564+
.asBitmap()
565+
.load(bitmap)
566+
.into(target);
567+
568+
verify(target).onResourceReady(eq(bitmap), any(Transition.class));
569+
}
570+
571+
@Test
572+
public void testLoadBitmap_asDrawable() {
573+
Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
574+
requestManager
575+
.load(bitmap)
576+
.into(target);
577+
578+
ArgumentCaptor<Object> captor = ArgumentCaptor.forClass(Object.class);
579+
verify(target).onResourceReady(captor.capture(), any(Transition.class));
580+
BitmapDrawable drawable = (BitmapDrawable) captor.getValue();
581+
assertThat(drawable.getBitmap()).isEqualTo(bitmap);
582+
}
583+
584+
@Test
585+
public void testLoadDrawable() {
586+
Drawable drawable = new ColorDrawable(Color.RED);
587+
requestManager
588+
.load(drawable)
589+
.into(target);
590+
591+
verify(target).onResourceReady(eq(drawable), any(Transition.class));
592+
}
593+
557594
@Test
558595
public void testNullModelPrefersFallbackDrawable() {
559596
Drawable placeholder = new ColorDrawable(Color.GREEN);

0 commit comments

Comments
 (0)