package com.bumptech.glide; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.os.ParcelFileDescriptor; import android.view.animation.Animation; import android.widget.ImageView; import com.bumptech.glide.load.DecodeFormat; import com.bumptech.glide.load.Encoder; import com.bumptech.glide.load.Key; import com.bumptech.glide.load.ResourceDecoder; import com.bumptech.glide.load.ResourceEncoder; import com.bumptech.glide.load.Transformation; import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; import com.bumptech.glide.load.model.ImageVideoWrapper; import com.bumptech.glide.load.resource.bitmap.BitmapTransformation; import com.bumptech.glide.load.resource.bitmap.Downsampler; import com.bumptech.glide.load.resource.bitmap.FileDescriptorBitmapDecoder; import com.bumptech.glide.load.resource.bitmap.ImageVideoBitmapDecoder; import com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder; import com.bumptech.glide.load.resource.bitmap.VideoBitmapDecoder; import com.bumptech.glide.load.resource.file.FileToStreamDecoder; import com.bumptech.glide.load.resource.transcode.ResourceTranscoder; import com.bumptech.glide.provider.LoadProvider; import com.bumptech.glide.request.RequestListener; import com.bumptech.glide.request.animation.ViewPropertyAnimation; import com.bumptech.glide.request.target.Target; import java.io.File; import java.io.InputStream; /** * A class for creating a request to load a bitmap for an image or from a video. Sets a variety of type independent * options including resizing, animations, and placeholders. * *

* Warning - It is not safe to use this builder after calling into(), it may be pooled and * reused. *

* * @param The type of model that will be loaded into the target. * @param The type of the transcoded resource that the target will receive */ public class BitmapRequestBuilder extends GenericRequestBuilder implements BitmapOptions { private final BitmapPool bitmapPool; private Downsampler downsampler = Downsampler.AT_LEAST; private DecodeFormat decodeFormat; private ResourceDecoder imageDecoder; private ResourceDecoder videoDecoder; BitmapRequestBuilder(LoadProvider loadProvider, Class transcodeClass, GenericRequestBuilder other) { super(loadProvider, transcodeClass, other); this.bitmapPool = other.glide.getBitmapPool(); this.decodeFormat = other.glide.getDecodeFormat(); imageDecoder = new StreamBitmapDecoder(bitmapPool, decodeFormat); videoDecoder = new FileDescriptorBitmapDecoder(bitmapPool, decodeFormat); } /** * Load images at a size near the size of the target using {@link Downsampler#AT_LEAST}. * * @see #downsample(Downsampler) * * @return This request builder. */ public BitmapRequestBuilder approximate() { return downsample(Downsampler.AT_LEAST); } /** * Load images at their original size using {@link Downsampler#NONE}. * * @see #downsample(Downsampler) * * @return This request builder. */ public BitmapRequestBuilder asIs() { return downsample(Downsampler.NONE); } /** * Load images at a size that is at most exactly as big as the target using * {@link com.bumptech.glide.load.resource.bitmap.Downsampler#AT_MOST}. * * @see #downsample(com.bumptech.glide.load.resource.bitmap.Downsampler) * * @return This request builder. */ public BitmapRequestBuilder atMost() { return downsample(Downsampler.AT_MOST); } /** * Load images using the given {@link Downsampler}. Replaces any existing image decoder. Defaults to * {@link Downsampler#AT_LEAST}. Will be ignored if the data represented by the model is a video. This replaces any * previous calls to {@link #imageDecoder(ResourceDecoder)} and {@link #decoder(ResourceDecoder)} with default * decoders with the appropriate options set. * * @see #imageDecoder * * @param downsampler The downsampler. * @return This request builder. */ private BitmapRequestBuilder downsample(Downsampler downsampler) { this.downsampler = downsampler; imageDecoder = new StreamBitmapDecoder(downsampler, bitmapPool, decodeFormat); super.decoder(new ImageVideoBitmapDecoder(imageDecoder, videoDecoder)); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder thumbnail(float sizeMultiplier) { super.thumbnail(sizeMultiplier); return this; } /** * Loads and displays the {@link android.graphics.Bitmap} retrieved by the given thumbnail request if it finishes * before this request. Best used for loading thumbnail {@link Bitmap}s that are smaller and will be loaded more * quickly than the fullsize {@link Bitmap}. There are no guarantees about the order in which the requests will * actually finish. However, if the thumb request completes after the full request, the thumb * {@link android.graphics.Bitmap} will never replace the full image. * * @see #thumbnail(float) * *

* Note - Any options on the main request will not be passed on to the thumbnail request. For example, if * you want an animation to occur when either the full {@link android.graphics.Bitmap} loads or the thumbnail * loads, you need to call {@link #animate(int)} on both the thumb and the full request. For a simpler thumbnail * option where these options are applied to the humbnail as well, see {@link #thumbnail(float)}. *

* *

* Only the thumbnail call on the main request will be obeyed, recursive calls to this method are ignored. *

* * @param thumbnailRequest The request to use to load the thumbnail. * @return This request builder. */ public BitmapRequestBuilder thumbnail(BitmapRequestBuilder thumbnailRequest) { super.thumbnail(thumbnailRequest); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder sizeMultiplier(float sizeMultiplier) { super.sizeMultiplier(sizeMultiplier); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder decoder(ResourceDecoder decoder) { super.decoder(decoder); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder cacheDecoder(ResourceDecoder cacheDecoder) { super.cacheDecoder(cacheDecoder); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder encoder(ResourceEncoder encoder) { super.encoder(encoder); return this; } /** * Sets the {@link com.bumptech.glide.load.ResourceDecoder} that will be used to decode {@link Bitmap}s obtained * from an {@link java.io.InputStream}. * * @see #videoDecoder * * @param decoder The decoder to use to decode {@link Bitmap}s. * @return This request builder. */ public BitmapRequestBuilder imageDecoder(ResourceDecoder decoder) { imageDecoder = decoder; super.decoder(new ImageVideoBitmapDecoder(decoder, videoDecoder)); return this; } /** * Sets the {@link com.bumptech.glide.load.ResourceDecoder} that will be used to decode {@link Bitmap}s obtained * from an {@link android.os.ParcelFileDescriptor}. * * @param decoder The decoder to use to decode {@link Bitmap}s. * @return This request builder. */ public BitmapRequestBuilder videoDecoder( ResourceDecoder decoder) { videoDecoder = decoder; super.decoder(new ImageVideoBitmapDecoder(imageDecoder, decoder)); return this; } /** * Sets the preferred format for {@link Bitmap}s decoded in this request. Defaults to * {@link DecodeFormat#PREFER_RGB_565}. This replaces any previous calls to {@link #imageDecoder(ResourceDecoder)}, * {@link #videoDecoder(ResourceDecoder)}, {@link #decoder(ResourceDecoder)} and * {@link #cacheDecoder(com.bumptech.glide.load.ResourceDecoder)}} with default decoders with the appropriate * options set. * *

* Note - If using a {@link Transformation} that expect bitmaps to support transparency, this should always be * set to ALWAYS_ARGB_8888. RGB_565 requires fewer bytes per pixel and is generally preferable, but it does not * support transparency. *

* * @see DecodeFormat * * @param format The format to use. * @return This request builder. */ public BitmapRequestBuilder format(DecodeFormat format) { this.decodeFormat = format; imageDecoder = new StreamBitmapDecoder(downsampler, bitmapPool, format); videoDecoder = new FileDescriptorBitmapDecoder(new VideoBitmapDecoder(), bitmapPool, format); super.cacheDecoder(new FileToStreamDecoder(new StreamBitmapDecoder(downsampler, bitmapPool, format))); super.decoder(new ImageVideoBitmapDecoder(imageDecoder, videoDecoder)); return this; } @Override public BitmapRequestBuilder priority(Priority priority) { super.priority(priority); return this; } /** * Transform images using the given {@link com.bumptech.glide.load.resource.bitmap.BitmapTransformation}s. * * @see #centerCrop() * @see #fitCenter() * @see #transform(com.bumptech.glide.load.Transformation[]) * * @param transformations The transformations to apply in order. * @return This request builder. */ public BitmapRequestBuilder transform(BitmapTransformation... transformations) { super.transform(transformations); return this; } /** * Transform images using {@link com.bumptech.glide.load.resource.bitmap.CenterCrop}. * * @see #fitCenter() * @see #transform(com.bumptech.glide.load.resource.bitmap.BitmapTransformation...) * @see #transform(com.bumptech.glide.load.Transformation[]) * * @return This request builder. */ public BitmapRequestBuilder centerCrop() { return transform(glide.getBitmapCenterCrop()); } /** * Transform images using {@link com.bumptech.glide.load.resource.bitmap.FitCenter}. * * @see #centerCrop() * @see #transform(com.bumptech.glide.load.resource.bitmap.BitmapTransformation...) * @see #transform(com.bumptech.glide.load.Transformation[]) * * @return This request builder. */ public BitmapRequestBuilder fitCenter() { return transform(glide.getBitmapFitCenter()); } /** * {@inheritDoc} * * @see #fitCenter() * @see #centerCrop() */ @Override public BitmapRequestBuilder transform(Transformation... transformations) { super.transform(transformations); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder transcoder( ResourceTranscoder transcoder) { super.transcoder(transcoder); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder dontAnimate() { super.dontAnimate(); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder animate(int animationId) { super.animate(animationId); return this; } /** * {@inheritDoc} */ @Deprecated @SuppressWarnings("deprecation") @Override public BitmapRequestBuilder animate(Animation animation) { super.animate(animation); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder animate(ViewPropertyAnimation.Animator animator) { super.animate(animator); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder placeholder(int resourceId) { super.placeholder(resourceId); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder placeholder(Drawable drawable) { super.placeholder(drawable); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder error(int resourceId) { super.error(resourceId); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder error(Drawable drawable) { super.error(drawable); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder listener( RequestListener requestListener) { super.listener(requestListener); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder skipMemoryCache(boolean skip) { super.skipMemoryCache(skip); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder diskCacheStrategy(DiskCacheStrategy strategy) { super.diskCacheStrategy(strategy); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder override(int width, int height) { super.override(width, height); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder thumbnail( GenericRequestBuilder thumbnailRequest) { super.thumbnail(thumbnailRequest); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder sourceEncoder(Encoder sourceEncoder) { super.sourceEncoder(sourceEncoder); return this; } /** * {@inheritDoc} */ @Override public BitmapRequestBuilder dontTransform() { super.dontTransform(); return this; } @Override public BitmapRequestBuilder signature(Key signature) { super.signature(signature); return this; } @Override public BitmapRequestBuilder load(ModelType model) { super.load(model); return this; } @Override public BitmapRequestBuilder clone() { return (BitmapRequestBuilder) super.clone(); } /** * {@inheritDoc} * *

* Note - If no transformation is set for this load, a default transformation will be applied based on the * value returned from {@link android.widget.ImageView#getScaleType()}. To avoid this default transformation, * use {@link #dontTransform()}. *

* * @param view {@inheritDoc} * @return {@inheritDoc} */ @Override public Target into(ImageView view) { return super.into(view); } @Override void applyFitCenter() { fitCenter(); } @Override void applyCenterCrop() { centerCrop(); } }