private RequestOptions 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(); }
@Override public void onResourceReady(Drawable resource, @Nullable Transition<? super Drawable> transition) { super.onResourceReady(resource, transition); BadgedFourThreeImageView badgedImageView = (BadgedFourThreeImageView) getView(); if (resource instanceof GifDrawable) { Bitmap image = ((GifDrawable) resource).getFirstFrame(); if (image != null) { // look at the corner to determine the gif badge color int cornerSize = (int) (56 * getView().getContext().getResources().getDisplayMetrics ().scaledDensity); Bitmap corner = Bitmap.createBitmap(image, image.getWidth() - cornerSize, image.getHeight() - cornerSize, cornerSize, cornerSize); boolean isDark = ColorUtils.isDark(corner); corner.recycle(); badgedImageView.setBadgeColor(ContextCompat.getColor(getView().getContext(), isDark ? R.color.gif_badge_dark_image : R.color.gif_badge_light_image)); } else { badgedImageView.setBadgeColor(ContextCompat.getColor(getView().getContext(), R.color.gif_badge_light_image)); } } }
@Override public void getData() { swipeRefreshLayout.setRefreshing(true); if (url.contains("gif") && !url.contains("large")) { url = Parse.parseImageUrl(url, 0); } list.clear(); list.add(getString(R.string.save)); if (!url.contains("large")) { list.add(getString(R.string.view_original_image)); } alertDialog = new AlertDialog.Builder(this) .setTitle(R.string.option) .setItems(list.toArray(new String[list.size()]), this).create(); LogUtils.d("Load image: " + url); if (url.contains("gif")) { Glide.with(this).asGif().load(url).into(new ImageViewTarget<GifDrawable>()); } else { Glide.with(this).load(url).into(new ImageViewTarget<>()); } }
@Nullable private Intent getShareIntentForImage(String sharingText) { File cachedImage = null; if (mImageResource instanceof GlideBitmapDrawable) { cachedImage = getCachedBitmap(((GlideBitmapDrawable) mImageResource).getBitmap()); } else if (mImageResource instanceof GifDrawable) { cachedImage = getCachedGif((GifDrawable) mImageResource); } if (cachedImage != null) { Uri sharedUri = StreamProvider.getUriForFile("derpibooru.derpy.ui.ImageActivity", cachedImage); if (sharedUri != null) { return new Intent() .setAction(Intent.ACTION_SEND) .putExtra(Intent.EXTRA_SUBJECT, sharingText) .putExtra(Intent.EXTRA_STREAM, sharedUri) .setDataAndType(sharedUri, mContext.getContentResolver().getType(sharedUri)) .setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); } } return null; }
@Nullable private File getCachedGif(GifDrawable gifDrawable) { try { File cacheDir = getImageCacheDir(); if (cacheDir == null) { throw new IOException("cache directory does not exist."); } if (gifDrawable.getData().length >= GIF_FILE_SIZE_LIMIT_BYTES) { return getCachedBitmap(gifDrawable.getFirstFrame()); } else { FileOutputStream stream = new FileOutputStream(cacheDir + SLASH_TEMP_GIF_FILE_NAME); stream.write(gifDrawable.getData()); stream.close(); return new File(cacheDir + SLASH_TEMP_GIF_FILE_NAME); } } catch (IOException e) { Log.e("ImageShare", "getCachedGif", e); } return null; }
@Override public boolean onResourceReady(TranscodeType resource, Object model, Target<TranscodeType> target, DataSource dataSource, boolean isFirstResource) { boolean callbackResult = this.callback != null && this.callback.onResourceReady(resource, model, target, dataSource, isFirstResource); Bitmap b = null; if (resource instanceof BitmapDrawable) { b = ((BitmapDrawable) resource).getBitmap(); } else if (resource instanceof GifDrawable) { b = ((GifDrawable) resource).getFirstFrame(); } else if (target instanceof BitmapHolder) { b = ((BitmapHolder) target).getBitmap(); } if (b != null) { start(b); } return callbackResult; }
@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); } }
private boolean encodeTransformedToStream(GifDrawable drawable, OutputStream os) { Transformation<Bitmap> transformation = drawable.getFrameTransformation(); GifDecoder decoder = decodeHeaders(drawable.getBuffer()); AnimatedGifEncoder encoder = factory.buildEncoder(); if (!encoder.start(os)) { return false; } for (int i = 0; i < decoder.getFrameCount(); i++) { Bitmap currentFrame = decoder.getNextFrame(); Resource<Bitmap> transformedResource = getTransformedFrame(currentFrame, transformation, drawable); try { if (!encoder.addFrame(transformedResource.get())) { return false; } int currentFrameIndex = decoder.getCurrentFrameIndex(); int delay = decoder.getDelay(currentFrameIndex); encoder.setDelay(delay); decoder.advance(); } finally { transformedResource.recycle(); } } return encoder.finish(); }
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; }
@Override public void initialize() { if (drawable instanceof BitmapDrawable) { ((BitmapDrawable) drawable).getBitmap().prepareToDraw(); } else if (drawable instanceof GifDrawable) { ((GifDrawable) drawable).getFirstFrame().prepareToDraw(); } }
@Test public void testReceivesGif() throws IOException { String fakeUri = "content://fake"; InputStream testGifData = openResource("test.gif"); mockUri(Uri.parse(fakeUri), testGifData); requestManager.asGif().load(fakeUri).into(target); verify(target).onResourceReady(isA(GifDrawable.class), isA(Transition.class)); }
@Test public void testReceivesGifBytes() throws IOException { String fakeUri = "content://fake"; InputStream testGifData = openResource("test.gif"); mockUri(Uri.parse(fakeUri), testGifData); requestManager.as(byte[].class).apply(decodeTypeOf(GifDrawable.class)).load(fakeUri) .into(target); verify(target).onResourceReady(isA(byte[].class), isA(Transition.class)); }
@Test public void testReturnsNewDrawableOnGet() { GifDrawable expected = mock(GifDrawable.class); Drawable.ConstantState constantState = mock(Drawable.ConstantState.class); when(constantState.newDrawable()).thenReturn(expected); when(drawable.getConstantState()).thenReturn(constantState); assertEquals(expected, resource.get()); verify(drawable).getConstantState(); verify(constantState).newDrawable(); }
@Before public void setUp() { gifDrawable = mock(GifDrawable.class); resource = mockResource(); when(resource.get()).thenReturn(gifDrawable); transcoder = new GifDrawableBytesTranscoder(); }
@NonNull @Override public RequestBuilder<GifDrawable> getPreloadRequestBuilder(MediaStoreData item) { MediaStoreSignature signature = new MediaStoreSignature(item.mimeType, item.dateModified, item.orientation); return requestBuilder .clone() .signature(signature) .load(item.uri); }
@Test public void getDefaultTransitionOptions_withSuperClassRegistered_returnsSuperClassOptions() { DrawableTransitionOptions expected = new DrawableTransitionOptions(); transitionOptions.put(Drawable.class, expected); assertThat(context.getDefaultTransitionOptions(BitmapDrawable.class)) .isEqualTo(expected); assertThat(context.getDefaultTransitionOptions(GifDrawable.class)) .isEqualTo(expected); }
@Test public void testReceivesGif() throws IOException { String fakeUri = "content://fake"; InputStream testGifData = openGif(); mockUri(Uri.parse(fakeUri), testGifData); requestManager.asGif().load(fakeUri).into(target); verify(target).onResourceReady(isA(GifDrawable.class), isA(Transition.class)); }
@Test public void testReceivesGifBytes() throws IOException { String fakeUri = "content://fake"; InputStream testGifData = openGif(); mockUri(Uri.parse(fakeUri), testGifData); requestManager.as(byte[].class).apply(decodeTypeOf(GifDrawable.class)).load(fakeUri) .into(target); verify(target).onResourceReady(isA(byte[].class), isA(Transition.class)); }
@Test public void testReturnsNewDrawableOnGet() { GifDrawable expected = mock(GifDrawable.class); Drawable.ConstantState constantState = mock(Drawable.ConstantState.class); when(constantState.newDrawable()).thenReturn(expected); when(drawable.getConstantState()).thenReturn(constantState); assertThat(resource.get()).isEqualTo(expected); verify(drawable).getConstantState(); verify(constantState).newDrawable(); }
@Override public void onResourceReady(T resource, Transition<? super T> transition) { gestureImageView.setImageDrawable(resource); if (resource instanceof GifDrawable) { ((GifDrawable) resource).start(); } swipeRefreshLayout.setRefreshing(false); }
@Override public void draw(Canvas canvas) { if (drawable != null) { drawable.draw(canvas); if (drawable instanceof GifDrawable) { if (!((GifDrawable) drawable).isRunning()) { ((GifDrawable) drawable).start(); } } } }
@Override public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> animation) { super.onResourceReady(resource, animation); if (!autoplayGifs) { resource.stop(); } BadgedFourThreeImageView badgedImageView = (BadgedFourThreeImageView) getView(); if (resource instanceof GlideBitmapDrawable) { Palette.from(((GlideBitmapDrawable) resource).getBitmap()) .clearFilters() .generate(this); } else if (resource instanceof GifDrawable) { Bitmap image = ((GifDrawable) resource).getFirstFrame(); Palette.from(image).clearFilters().generate(this); // look at the corner to determine the gif badge color int cornerSize = (int) (56 * getView().getContext().getResources().getDisplayMetrics ().scaledDensity); Bitmap corner = Bitmap.createBitmap(image, image.getWidth() - cornerSize, image.getHeight() - cornerSize, cornerSize, cornerSize); boolean isDark = ColorUtils.isDark(corner); corner.recycle(); badgedImageView.setBadgeColor(ContextCompat.getColor(getView().getContext(), isDark ? R.color.gif_badge_dark_image : R.color.gif_badge_light_image)); } }
public static Bitmap getBitmap(GlideDrawable glideDrawable) { if (glideDrawable instanceof GlideBitmapDrawable) { return ((GlideBitmapDrawable) glideDrawable).getBitmap(); } else if (glideDrawable instanceof GifDrawable) { return ((GifDrawable) glideDrawable).getFirstFrame(); } return null; }
public static void hybridImplementation(String u, final ImageView target, Context context, final Runnable callback) { if (u.contains(".gif")) { Glide.with(context).asGif().load(u) .apply(getOpt()) .into(new ImageViewTarget<GifDrawable>(target) { @Override protected void setResource(GifDrawable resource) { target.setImageDrawable(resource); callback.run(); } }); } else { picassoImplementation(u, target, context, callback); } }
@Override public void recycle() { Glide.clear(this); if (gifDrawableSoftReference != null) { GifDrawable gifDrawable = gifDrawableSoftReference.get(); if (gifDrawable != null) { gifDrawable.setCallback(null); gifDrawable.stop(); } } }
@Override public void onResourceReady(GifDrawable resource, GlideAnimation<? super GifDrawable> glideAnimation) { if (!activityIsAlive()) { return; } DrawableWrapper drawableWrapper = urlDrawableWeakReference.get(); if (drawableWrapper == null) { return; } holder.setImageState(ImageHolder.ImageState.READY); gifDrawableSoftReference = new SoftReference<>(resource); Bitmap first = resource.getFirstFrame(); holder.setSize(first.getWidth(), first.getHeight()); drawableWrapper.setDrawable(resource); if (rect != null) { drawableWrapper.setBounds(rect); } else { if (!config.autoFix && config.imageFixCallback != null) { config.imageFixCallback.onImageReady(holder, first.getWidth(), first.getHeight()); } if (config.autoFix || holder.isAutoFix() || !holder.isInvalidateSize()) { int width = getRealWidth(); int height = (int) ((float) first.getHeight() * width / first.getWidth()); drawableWrapper.setBounds(0, 0, width, height); } else { drawableWrapper.setBounds(0, 0, holder.getWidth(), holder.getHeight()); } if (holder.isAutoPlay()) { resource.setCallback(this); resource.start(); resource.setLoopCount(GlideDrawable.LOOP_FOREVER); } } resetText(); loadDone(); }
@Override public Resource<byte[]> transcode(Resource<GifDrawable> toTranscode) { GifDrawable gifData = toTranscode.get(); ByteBuffer byteBuffer = gifData.getBuffer(); return new BytesResource(ByteBufferUtil.toBytes(byteBuffer)); }
@Override @CheckResult public GlideRequest<GifDrawable> asGif() { return (GlideRequest<GifDrawable>) super.asGif(); }
@Override public Resource<byte[]> transcode(Resource<GifDrawable> toTranscode, Options options) { GifDrawable gifData = toTranscode.get(); ByteBuffer byteBuffer = gifData.getBuffer(); return new BytesResource(ByteBufferUtil.toBytes(byteBuffer)); }