@Override public Resource<Bitmap> transform(Resource<Bitmap> resource, int outWidth, int outHeight) { Bitmap source = resource.get(); int width = source.getWidth(); int height = source.getHeight(); Bitmap result = mBitmapPool.get(width, height, Bitmap.Config.ARGB_8888); if (result == null) { result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); } Canvas canvas = new Canvas(result); canvas.drawBitmap(source, 0, 0, mMaskingPaint); canvas.drawColor(0x44000000); return BitmapResource.obtain(result, mBitmapPool); }
@Test public void testPassesGivenArgumentsToTransform() { final int expectedWidth = 13; final int expectedHeight = 148; final Resource<Bitmap> resource = mockResource(223, 4123); BitmapTransformation transformation = new BitmapTransformation() { @Override public void updateDiskCacheKey(MessageDigest messageDigest) { } @Override protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) { assertEquals(bitmapPool, pool); assertEquals(resource.get(), toTransform); assertEquals(expectedWidth, outWidth); assertEquals(expectedHeight, outHeight); return resource.get(); } }; transformation.transform(context, resource, expectedWidth, expectedHeight); }
@Override public final Resource<Bitmap> transform( Context context, Resource<Bitmap> resource, int outWidth, int outHeight) { if (!Util.isValidDimensions(outWidth, outHeight)) { throw new IllegalArgumentException( "Cannot apply transformation on width: " + outWidth + " or height: " + outHeight + " less than or equal to zero and not Target.SIZE_ORIGINAL"); } BitmapPool bitmapPool = Glide.get(context).getBitmapPool(); Bitmap toTransform = resource.get(); int targetWidth = outWidth == Target.SIZE_ORIGINAL ? toTransform.getWidth() : outWidth; int targetHeight = outHeight == Target.SIZE_ORIGINAL ? toTransform.getHeight() : outHeight; Bitmap transformed = transform(bitmapPool, toTransform, targetWidth, targetHeight); final Resource<Bitmap> result; if (toTransform.equals(transformed)) { result = resource; } else { result = BitmapResource.obtain(transformed, bitmapPool); } return result; }
@Test @SuppressWarnings("unchecked") public void testSetsTransformationAsFrameTransformation() { Resource<GifDrawable> resource = mockResource(); GifDrawable gifDrawable = mock(GifDrawable.class); Transformation<Bitmap> unitTransformation = UnitTransformation.get(); when(gifDrawable.getFrameTransformation()).thenReturn(unitTransformation); when(gifDrawable.getIntrinsicWidth()).thenReturn(500); when(gifDrawable.getIntrinsicHeight()).thenReturn(500); when(resource.get()).thenReturn(gifDrawable); Bitmap firstFrame = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); when(gifDrawable.getFirstFrame()).thenReturn(firstFrame); final int width = 123; final int height = 456; Bitmap expectedBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Resource<Bitmap> expectedResource = mockResource(); when(expectedResource.get()).thenReturn(expectedBitmap); when(wrapped.transform(any(Context.class), Util.<Bitmap>anyResource(), anyInt(), anyInt())) .thenReturn(expectedResource); transformation.transform(context, resource, width, height); verify(gifDrawable).setFrameTransformation(isA(Transformation.class), eq(expectedBitmap)); }
private ImageWrapper decodeGifWrapper(InputStream bis, int width, int height) throws IOException { ImageWrapper result = null; Resource<GifDrawable> gifResource = gifDecoder.decode(bis, width, height); if (gifResource != null) { GifDrawable drawable = gifResource.get(); // We can more efficiently hold Bitmaps in memory, so for static GIFs, try to return Bitmaps // instead. Returning a Bitmap incurs the cost of allocating the GifDrawable as well as the normal // Bitmap allocation, but since we can encode the Bitmap out as a JPEG, future decodes will be // efficient. if (drawable.getNumberOfFrames() > 1) { result = new ImageWrapper(null /*bitmapResource*/, gifResource); } else { Resource<Bitmap> bitmapResource = new BitmapResource(drawable.getCurrentFrame(), bitmapPool); result = new ImageWrapper(bitmapResource, null /*gifResource*/); } } return result; }
@Override public Resource<Bitmap> transform(Resource<Bitmap> resource, int outWidth, int outHeight) { Bitmap source = resource.get(); int width = source.getWidth(); int height = source.getHeight(); Bitmap.Config config = source.getConfig() != null ? source.getConfig() : Bitmap.Config.ARGB_8888; Bitmap bitmap = mBitmapPool.get(width, height, config); if (bitmap == null) { bitmap = Bitmap.createBitmap(width, height, config); } Canvas canvas = new Canvas(bitmap); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColorFilter(new PorterDuffColorFilter(mColor, PorterDuff.Mode.SRC_ATOP)); canvas.drawBitmap(source, 0, 0, paint); return BitmapResource.obtain(bitmap, mBitmapPool); }
private static <T> Bitmap createScaledBitmapInto(Context context, T model, int width, int height) throws BitmapDecodingException { final Bitmap rough = Downsampler.AT_LEAST .decode(getInputStreamForModel(context, model), Glide.get(context).getBitmapPool(), width, height, DecodeFormat.PREFER_RGB_565); final Resource<Bitmap> resource = BitmapResource .obtain(rough, Glide.get(context).getBitmapPool()); final Resource<Bitmap> result = new FitCenter(context).transform(resource, width, height); if (result == null) { throw new BitmapDecodingException("unable to transform Bitmap"); } return result.get(); }
@Test public void testProvidesBitmapFromGivenResourceToWrappedTransformation() { int outWidth = 332; int outHeight = 111; Resource<Bitmap> transformed = Util.mockResource(); when(transformed.get()) .thenReturn(Bitmap.createBitmap(outWidth, outHeight, Bitmap.Config.ARGB_8888)); when(wrapped.transform(anyContext(), Util.<Bitmap>anyResource(), anyInt(), anyInt())) .thenReturn(transformed); transformation.transform(context, drawableResourceToTransform, outWidth, outHeight); ArgumentCaptor<Resource<Bitmap>> captor = Util.cast(ArgumentCaptor.forClass(Resource.class)); verify(wrapped).transform(anyContext(), captor.capture(), eq(outWidth), eq(outHeight)); assertThat(captor.getValue().get()).isEqualTo(bitmapToTransform); }
@Test public void testReturnsGivenResourceWhenBitmapNotTransformed() { BitmapTransformation transformation = new BitmapTransformation() { @Override public void updateDiskCacheKey(MessageDigest messageDigest) { } @Override protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) { return toTransform; } }; Resource<Bitmap> resource = mockResource(100, 100); assertEquals(resource, transformation.transform(context, resource, 1, 1)); }
@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(); }
@Test public void testReturnsNewResourceWhenBitmapTransformed() { final Bitmap transformed = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_4444); BitmapTransformation transformation = new BitmapTransformation() { @Override public void updateDiskCacheKey(MessageDigest messageDigest) { } @Override protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap bitmap, int outWidth, int outHeight) { return transformed; } }; Resource<Bitmap> resource = mockResource(1, 2); assertNotSame(resource, transformation.transform(context, resource, 100, 100)); }
private static <T> Bitmap createScaledBitmapInto(Context context, T model, int width, int height) throws BitmapDecodingException { final Bitmap rough = Downsampler.AT_LEAST.decode(getInputStreamForModel(context, model), Glide.get(context).getBitmapPool(), width, height, DecodeFormat.PREFER_RGB_565); final Resource<Bitmap> resource = BitmapResource.obtain(rough, Glide.get(context).getBitmapPool()); final Resource<Bitmap> result = new FitCenter(context).transform(resource, width, height); if (result == null) { throw new BitmapDecodingException("unable to transform Bitmap"); } return result.get(); }
@Test public void testReturnsNewResourceIfTransformationDoesTransform() { int outWidth = 999; int outHeight = 555; Bitmap transformedBitmap = Bitmap.createBitmap(outWidth, outHeight, Bitmap.Config.RGB_565); Resource<Bitmap> transformedBitmapResource = Util.mockResource(); when(transformedBitmapResource.get()).thenReturn(transformedBitmap); when(wrapped.transform(anyContext(), Util.<Bitmap>anyResource(), eq(outWidth), eq(outHeight))) .thenReturn(transformedBitmapResource); Resource<BitmapDrawable> transformed = transformation.transform(context, drawableResourceToTransform, outWidth, outHeight); assertThat(transformed.get().getBitmap()).isEqualTo(transformedBitmap); }
@Test public void testReturnsNullIfTransformReturnsNull() { BitmapTransformation transform = new BitmapTransformation() { @Override public void updateDiskCacheKey(MessageDigest messageDigest) { } @Override protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) { return null; } }; Resource<Bitmap> resource = mockResource(100, 100); assertNull(transform.transform(context, resource, 100, 100)); }
@Test public void testSizeIsBasedOnResource() { LruResourceCache resourceCache = new LruResourceCache(100); Resource<?> first = getResource(50); MockKey firstKey = new MockKey(); resourceCache.put(firstKey, first); Resource<?> second = getResource(50); MockKey secondKey = new MockKey(); resourceCache.put(secondKey, second); assertTrue(resourceCache.contains(firstKey)); assertTrue(resourceCache.contains(secondKey)); Resource<?> third = getResource(50); MockKey thirdKey = new MockKey(); resourceCache.put(thirdKey, third); assertFalse(resourceCache.contains(firstKey)); assertTrue(resourceCache.contains(secondKey)); assertTrue(resourceCache.contains(thirdKey)); }
@Override public Resource<Bitmap> transform(Resource<Bitmap> resource, int outWidth, int outHeight) { Bitmap source = resource.get(); int width = source.getWidth(); int height = source.getHeight(); Bitmap bitmap = mBitmapPool.get(width, height, Bitmap.Config.RGB_565); if (bitmap == null) { bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); } Canvas canvas = new Canvas(bitmap); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)); drawRoundRect(canvas, paint, width, height); return BitmapResource.obtain(bitmap, mBitmapPool); }
@Override public Resource<GifDrawable> transform( Context context, Resource<GifDrawable> resource, int outWidth, int outHeight) { GifDrawable drawable = resource.get(); // The drawable needs to be initialized with the correct width and height in order for a view // displaying it to end up with the right dimensions. Since our transformations may arbitrarily // modify the dimensions of our GIF, here we create a stand in for a frame and pass it to the // transformation to see what the final transformed dimensions will be so that our drawable can // report the correct intrinsic width and height. BitmapPool bitmapPool = Glide.get(context).getBitmapPool(); Bitmap firstFrame = drawable.getFirstFrame(); Resource<Bitmap> bitmapResource = new BitmapResource(firstFrame, bitmapPool); Resource<Bitmap> transformed = wrapped.transform(context, bitmapResource, outWidth, outHeight); if (!bitmapResource.equals(transformed)) { bitmapResource.recycle(); } Bitmap transformedFrame = transformed.get(); drawable.setFrameTransformation(wrapped, transformedFrame); return resource; }
@Test public void testReturnsOriginalResourceIfTransformationDoesNotTransform() { int outWidth = 123; int outHeight = 456; when(wrapped.transform( anyContext(), Util.<Bitmap>anyResource(), eq(outWidth), eq(outHeight))) .thenAnswer(new Answer<Resource<Bitmap>>() { @SuppressWarnings("unchecked") @Override public Resource<Bitmap> answer(InvocationOnMock invocation) throws Throwable { return (Resource<Bitmap>) invocation.getArguments()[1]; } }); Resource<BitmapDrawable> transformed = transformation.transform(context, drawableResourceToTransform, outWidth, outHeight); assertThat(transformed).isEqualTo(drawableResourceToTransform); }
@Override public Resource<Drawable> transform(Context context, 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.get()); } }
@Nullable static Resource<Bitmap> convert(BitmapPool bitmapPool, Drawable drawable, int width, int height) { // Handle DrawableContainer or StateListDrawables that may contain one or more BitmapDrawables. drawable = drawable.getCurrent(); Bitmap result = null; boolean isRecycleable = false; if (drawable instanceof BitmapDrawable) { result = ((BitmapDrawable) drawable).getBitmap(); } else if (!(drawable instanceof Animatable)) { result = drawToBitmap(bitmapPool, drawable, width, height); // We created and drew to the Bitmap, so it's safe for us to recycle or re-use. isRecycleable = true; } BitmapPool toUse = isRecycleable ? bitmapPool : NO_RECYCLE_BITMAP_POOL; return BitmapResource.obtain(result, toUse); }
@Override public Resource<Bitmap> decode(FallbackGlideParams source, int width, int height) throws IOException { BitmapPool pool = Glide.get(context).getBitmapPool(); Bitmap bitmap = pool.getDirty(mPictureSizeInPx, mPictureSizeInPx, Bitmap.Config.ARGB_8888); if (bitmap == null) { bitmap = Bitmap.createBitmap(mPictureSizeInPx, mPictureSizeInPx, Bitmap.Config.ARGB_8888); } drawTextAndBgColorOnBitmap(bitmap, source); return BitmapResource.obtain(bitmap, pool); }
@Override public boolean encode(Resource<GifDrawable> resource, File file, Options options) { GifDrawable drawable = resource.get(); Transformation<Bitmap> transformation = drawable.getFrameTransformation(); boolean isTransformed = !(transformation instanceof UnitTransformation); if (isTransformed && options.get(ENCODE_TRANSFORMATION)) { return encodeTransformedToFile(drawable, file); } else { return writeDataDirect(drawable.getBuffer(), file); } }
public ImageWrapper(Resource<Bitmap> bitmapResource, Resource<GifDrawable> gifResource) { if (bitmapResource != null && gifResource != null) { throw new IllegalArgumentException("Can only contain either a bitmap resource or a gif resource, not both"); } else if (bitmapResource == null && gifResource == null) { throw new IllegalArgumentException("Must contain either a bitmap resource or a gif resource"); } else { this.bitmapResource = bitmapResource; this.gifResource = gifResource; } }
private Resource<Bitmap> getTransformedFrame(Bitmap currentFrame, Transformation<Bitmap> transformation, GifDrawable drawable) { // TODO: what if current frame is null? Resource<Bitmap> bitmapResource = factory.buildFrameResource(currentFrame, bitmapPool); Resource<Bitmap> transformedResource = transformation.transform( context, bitmapResource, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); if (!bitmapResource.equals(transformedResource)) { bitmapResource.recycle(); } return transformedResource; }
@SuppressWarnings("unchecked") @Before public void setUp() { MockitoAnnotations.initMocks(this); Application context = RuntimeEnvironment.application; ReEncodingGifResourceEncoder.Factory factory = mock(ReEncodingGifResourceEncoder.Factory.class); when(factory.buildDecoder(any(GifDecoder.BitmapProvider.class))).thenReturn(decoder); when(factory.buildParser()).thenReturn(parser); when(factory.buildEncoder()).thenReturn(gifEncoder); when(factory.buildFrameResource(any(Bitmap.class), any(BitmapPool.class))) .thenReturn(frameResource); // TODO Util.anyResource once Util is moved to testutil module (remove unchecked above!) when(frameTransformation.transform(anyContext(), any(Resource.class), anyInt(), anyInt())) .thenReturn(frameResource); when(gifDrawable.getFrameTransformation()).thenReturn(frameTransformation); when(gifDrawable.getBuffer()).thenReturn(ByteBuffer.allocate(0)); when(resource.get()).thenReturn(gifDrawable); encoder = new ReEncodingGifResourceEncoder(context, mock(BitmapPool.class), factory); options = new Options(); options.set(ReEncodingGifResourceEncoder.ENCODE_TRANSFORMATION, true); file = new File(context.getCacheDir(), "test"); }
public Resource<SVG> decode(InputStream source, int width, int height, Options options) throws IOException { try { SVG svg = SVG.getFromInputStream(source); return new SimpleResource<SVG>(svg); } catch (SVGParseException ex) { throw new IOException("Cannot load SVG from stream", ex); } }
@Override public Resource<PictureDrawable> transcode(Resource<SVG> toTranscode) { SVG svg = toTranscode.get(); Picture picture = svg.renderToPicture(); PictureDrawable drawable = new PictureDrawable(picture); return new SimpleResource<PictureDrawable>(drawable); }
@Override public Resource<Bitmap> transform(Resource<Bitmap> resource, int outWidth, int outHeight) { Bitmap source = resource.get(); int size = Math.min(source.getWidth(), source.getHeight()); int width = (source.getWidth() - size) / 2; int height = (source.getHeight() - size) / 2; Bitmap bitmap = mBitmapPool.get(size, size, Bitmap.Config.ARGB_8888); if (bitmap == null) { bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); } Canvas canvas = new Canvas(bitmap); Paint paint = new Paint(); BitmapShader shader = new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP); if (width != 0 || height != 0) { Matrix matrix = new Matrix(); matrix.setTranslate(-width, -height); shader.setLocalMatrix(matrix); } paint.setShader(shader); paint.setAntiAlias(true); float r = size / 2f; canvas.drawCircle(r, r, r, paint); return BitmapResource.obtain(bitmap, mBitmapPool); }
@Test public void testReturnsGivenResourceIfMatchesSizeExactly() { Resource<Bitmap> result = fitCenter.transform(context, resource, bitmapWidth, bitmapHeight); assertEquals(resource, result); }
@Override public boolean encode(Resource<GifDrawable> data, File file, Options options) { GifDrawable drawable = data.get(); boolean success = false; try { ByteBufferUtil.toFile(drawable.getBuffer(), file); success = true; } catch (IOException e) { if (Log.isLoggable(TAG, Log.WARN)) { Log.w(TAG, "Failed to encode GIF drawable data", e); } } return success; }
@SuppressWarnings("resource") // @see ResourceDecoder.decode @Override public Resource<ImageWrapper> decode(ImageVideoWrapper source, int width, int height) throws IOException { ByteArrayPool pool = ByteArrayPool.get(); byte[] tempBytes = pool.getBytes(); ImageWrapper wrapper = null; try { wrapper = decode(source, width, height, tempBytes); } finally { pool.releaseBytes(tempBytes); } return wrapper != null ? new ImageWrapperResource(wrapper) : null; }
@Override public Resource<Bitmap> decode(ParcelFileDescriptor resource, int outWidth, int outHeight, Options options) throws IOException { long frameTimeMicros = options.get(TARGET_FRAME); if (frameTimeMicros < 0 && frameTimeMicros != DEFAULT_FRAME) { throw new IllegalArgumentException( "Requested frame must be non-negative, or DEFAULT_FRAME, given: " + frameTimeMicros); } Integer frameOption = options.get(FRAME_OPTION); final Bitmap result; MediaMetadataRetriever mediaMetadataRetriever = factory.build(); try { mediaMetadataRetriever.setDataSource(resource.getFileDescriptor()); if (frameTimeMicros == DEFAULT_FRAME) { result = mediaMetadataRetriever.getFrameAtTime(); } else if (frameOption == null) { result = mediaMetadataRetriever.getFrameAtTime(frameTimeMicros); } else { result = mediaMetadataRetriever.getFrameAtTime(frameTimeMicros, frameOption); } } finally { mediaMetadataRetriever.release(); } resource.close(); return BitmapResource.obtain(result, bitmapPool); }
@Override public Resource<byte[]> transcode(Resource<Bitmap> toTranscode) { ByteArrayOutputStream os = new ByteArrayOutputStream(); toTranscode.get().compress(compressFormat, quality, os); toTranscode.recycle(); return new BytesResource(os.toByteArray()); }
@Override public Resource<PaletteBitmap> transcode(Resource<Bitmap> toTranscode) { Bitmap bitmap = toTranscode.get(); Palette palette = new Palette.Builder(bitmap).generate(); PaletteBitmap result = new PaletteBitmap(bitmap, palette); return new PaletteBitmapResource(result, bitmapPool); }
@Override public Resource<Bitmap> transform(Resource<Bitmap> resource, int outWidth, int outHeight) { Bitmap source = resource.get(); int size = Math.min(source.getWidth(), source.getHeight()); int width = (source.getWidth() - size) / 2; int height = (source.getHeight() - size) / 2; Bitmap bitmap = mBitmapPool.get(size, size, Bitmap.Config.ARGB_8888); if (bitmap == null) { bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); } Canvas canvas = new Canvas(bitmap); Paint paint = new Paint(); BitmapShader shader = new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP); if (width != 0 || height != 0) { // source isn't square, move viewport to center Matrix matrix = new Matrix(); matrix.setTranslate(-width, -height); shader.setLocalMatrix(matrix); } paint.setShader(shader); paint.setAntiAlias(true); float r = size / 2f; canvas.drawCircle(r, r, r, paint); return BitmapResource.obtain(bitmap, mBitmapPool); }
public <X> ResourceEncoder<X> getResultEncoder(Resource<X> resource) throws NoResultEncoderAvailableException { ResourceEncoder<X> resourceEncoder = resourceEncoderRegistry.get(resource.getResourceClass()); if (resourceEncoder != null) { return resourceEncoder; } throw new NoResultEncoderAvailableException(resource.getResourceClass()); }
@SuppressWarnings("unchecked") private static Resource<BitmapDrawable> convertToBitmapDrawableResource( Resource<Drawable> resource) { if (!(resource.get() instanceof BitmapDrawable)) { throw new IllegalArgumentException( "Wrapped transformation unexpectedly returned a non BitmapDrawable resource: " + resource.get()); } return (Resource<BitmapDrawable>) (Resource<?>) resource; }
/** * Returns a Bitmap decoded from the given {@link InputStream} that is rotated to match any EXIF * data present in the stream and that is downsampled according to the given dimensions and any * provided {@link com.bumptech.glide.load.resource.bitmap.DownsampleStrategy} option. * * <p> If a Bitmap is present in the * {@link com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool} whose dimensions exactly match * those of the image for the given InputStream is available, the operation is much less expensive * in terms of memory. </p> * * <p> The provided {@link java.io.InputStream} must return <code>true</code> from * {@link java.io.InputStream#markSupported()} and is expected to support a reasonably large * mark limit to accommodate reading large image headers (~5MB). </p> * * @param is An {@link InputStream} to the data for the image. * @param requestedWidth The width the final image should be close to. * @param requestedHeight The height the final image should be close to. * @param options A set of options that may contain one or more supported options that influence * how a Bitmap will be decoded from the given stream. * @param callbacks A set of callbacks allowing callers to optionally respond to various * significant events during the decode process. * @return A new bitmap containing the image from the given InputStream, or recycle if recycle is * not null. */ @SuppressWarnings({"resource", "deprecation"}) public Resource<Bitmap> decode(InputStream is, int requestedWidth, int requestedHeight, Options options, DecodeCallbacks callbacks) throws IOException { Preconditions.checkArgument(is.markSupported(), "You must provide an InputStream that supports" + " mark()"); byte[] bytesForOptions = byteArrayPool.get(ArrayPool.STANDARD_BUFFER_SIZE_BYTES, byte[].class); BitmapFactory.Options bitmapFactoryOptions = getDefaultOptions(); bitmapFactoryOptions.inTempStorage = bytesForOptions; DecodeFormat decodeFormat = options.get(DECODE_FORMAT); DownsampleStrategy downsampleStrategy = options.get(DOWNSAMPLE_STRATEGY); boolean fixBitmapToRequestedDimensions = options.get(FIX_BITMAP_SIZE_TO_REQUESTED_DIMENSIONS); boolean isHardwareConfigAllowed = options.get(ALLOW_HARDWARE_CONFIG) != null && options.get(ALLOW_HARDWARE_CONFIG); if (decodeFormat == DecodeFormat.PREFER_ARGB_8888_DISALLOW_HARDWARE) { isHardwareConfigAllowed = false; } try { Bitmap result = decodeFromWrappedStreams(is, bitmapFactoryOptions, downsampleStrategy, decodeFormat, isHardwareConfigAllowed, requestedWidth, requestedHeight, fixBitmapToRequestedDimensions, callbacks); return BitmapResource.obtain(result, bitmapPool); } finally { releaseOptions(bitmapFactoryOptions); byteArrayPool.put(bytesForOptions); } }
@Test public void testReturnsBitmapDrawableResourceContainingGivenBitmap() { Bitmap expected = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); Resource<Bitmap> resource = mockResource(); when(resource.get()).thenReturn(expected); Resource<BitmapDrawable> transcoded = transcoder.transcode(resource, new Options()); assertEquals(expected, transcoded.get().getBitmap()); }