@NonNull T transform( @NonNull Transformation<Bitmap> transformation, boolean isRequired) { if (isAutoCloneEnabled) { return clone().transform(transformation, isRequired); } DrawableTransformation drawableTransformation = new DrawableTransformation(transformation, isRequired); transform(Bitmap.class, transformation, isRequired); transform(Drawable.class, drawableTransformation, isRequired); // TODO: remove BitmapDrawable decoder and this transformation. // Registering as BitmapDrawable is simply an optimization to avoid some iteration and // isAssignableFrom checks when obtaining the transformation later on. It can be removed without // affecting the functionality. transform(BitmapDrawable.class, drawableTransformation.asBitmapDrawable(), isRequired); transform(GifDrawable.class, new GifDrawableTransformation(transformation), isRequired); return selfOrThrowIfLocked(); }
@NonNull @Override public Resource<Drawable> transform(@NonNull Context context, @NonNull Resource<Drawable> resource, int outWidth, int outHeight) { BitmapPool bitmapPool = Glide.get(context).getBitmapPool(); Drawable drawable = resource.get(); Resource<Bitmap> bitmapResourceToTransform = DrawableToBitmapConverter.convert(bitmapPool, drawable, outWidth, outHeight); if (bitmapResourceToTransform == null) { if (isRequired) { throw new IllegalArgumentException("Unable to convert " + drawable + " to a Bitmap"); } else { return resource; } } Resource<Bitmap> transformedBitmapResource = wrapped.transform(context, bitmapResourceToTransform, outWidth, outHeight); if (transformedBitmapResource.equals(bitmapResourceToTransform)) { transformedBitmapResource.recycle(); return resource; } else { return newDrawableResource(context, transformedBitmapResource); } }
@SuppressWarnings("WeakerAccess") public BitmapDrawableTransformation(Transformation<Bitmap> wrapped) { this.wrapped = Preconditions.checkNotNull(new DrawableTransformation(wrapped, /*isRequired=*/ false)); }
@Test public void transform_withBitmapDrawable_andFunctionalBitmapTransformation_doesNotRecycle() { when(bitmapTransformation.transform( any(Context.class), anyBitmapResource(), anyInt(), anyInt())) .thenAnswer(new Answer<Resource<Bitmap>>() { @Override public Resource<Bitmap> answer(InvocationOnMock invocationOnMock) throws Throwable { return BitmapResource.obtain( Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888), bitmapPool); } }); Bitmap bitmap = Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888); BitmapDrawable drawable = new BitmapDrawable(context.getResources(), bitmap); @SuppressWarnings("unchecked") Resource<Drawable> input = (Resource<Drawable>) (Resource<?>) new BitmapDrawableResource(drawable, bitmapPool); transformation.transform(context, input, /*outWidth=*/ 100, /*outHeight=*/ 200); assertThat(bitmap.isRecycled()).isFalse(); }
@Test public void testEquals() { BitmapTransformation otherBitmapTransformation = mock(BitmapTransformation.class); doAnswer(new Util.WriteDigest("bitmapTransformation")) .when(bitmapTransformation).updateDiskCacheKey(any(MessageDigest.class)); doAnswer(new Util.WriteDigest("otherBitmapTransformation")) .when(otherBitmapTransformation).updateDiskCacheKey(any(MessageDigest.class)); keyTester .addEquivalenceGroup( transformation, new DrawableTransformation(bitmapTransformation, /*isRequired=*/ true), new DrawableTransformation(bitmapTransformation, /*isRequired=*/ false)) .addEquivalenceGroup(bitmapTransformation) .addEquivalenceGroup(otherBitmapTransformation) .addEquivalenceGroup( new DrawableTransformation(otherBitmapTransformation, /*isRequired=*/ true), new DrawableTransformation(otherBitmapTransformation, /*isRequired=*/ false)) .addRegressionTest( new DrawableTransformation(bitmapTransformation, /*isRequired=*/ true), "eddf60c557a6315a489b8a3a19b12439a90381256289fbe9a503afa726230bd9") .addRegressionTest( new DrawableTransformation(otherBitmapTransformation, /*isRequired=*/ false), "40931536ed0ec97c39d4be10c44f5b69a86030ec575317f5a0f17e15a0ea9be8") .test(); }
@Test public void transform_withBitmapDrawable_andUnitBitmapTransformation_doesNotRecycle() { when( bitmapTransformation .transform( any(Context.class), anyBitmapResource(), anyInt(), anyInt())) .thenAnswer(new ReturnGivenResource()); Bitmap bitmap = Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888); BitmapDrawable drawable = new BitmapDrawable(context.getResources(), bitmap); @SuppressWarnings("unchecked") Resource<Drawable> input = (Resource<Drawable>) (Resource<?>) new BitmapDrawableResource(drawable, bitmapPool); transformation.transform(context, input, /*outWidth=*/ 100, /*outHeight=*/ 200); assertThat(bitmap.isRecycled()).isFalse(); }
@Before public void setUp() { MockitoAnnotations.initMocks(this); transformation = new DrawableTransformation(bitmapTransformation, /*isRequired=*/ true); context = RuntimeEnvironment.application; bitmapPool = new BitmapPoolAdapter(); Glide.init(context, new GlideBuilder().setBitmapPool(bitmapPool)); }
transformation.transform(context, input, /*outWidth=*/ 100, /*outHeight=*/ 200);