下面列出了怎么用com.bumptech.glide.gifdecoder.GifDecoder的API类实例代码及写法,或者点击链接到github查看源代码。
private static GenericRequestBuilder<GifDecoder, GifDecoder, Bitmap, Bitmap> getRequestBuilder(Context context,
GifDecoder gifDecoder, int width, int height, BitmapPool bitmapPool) {
GifFrameResourceDecoder frameResourceDecoder = new GifFrameResourceDecoder(bitmapPool);
GifFrameModelLoader frameLoader = new GifFrameModelLoader();
Encoder<GifDecoder> sourceEncoder = NullEncoder.get();
return Glide.with(context)
.using(frameLoader, GifDecoder.class)
.load(gifDecoder)
.as(Bitmap.class)
.sourceEncoder(sourceEncoder)
.decoder(frameResourceDecoder)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.override(width, height);
}
public GifState(GifHeader header, byte[] data, Context context,
Transformation<Bitmap> frameTransformation, int targetWidth, int targetHeight,
GifDecoder.BitmapProvider provider, BitmapPool bitmapPool, Bitmap firstFrame) {
if (firstFrame == null) {
throw new NullPointerException("The first frame of the GIF must not be null");
}
gifHeader = header;
this.data = data;
this.bitmapPool = bitmapPool;
this.firstFrame = firstFrame;
this.context = context.getApplicationContext();
this.frameTransformation = frameTransformation;
this.targetWidth = targetWidth;
this.targetHeight = targetHeight;
bitmapProvider = provider;
}
private GifDrawableResource decode(byte[] data, int width, int height, GifHeaderParser parser, GifDecoder decoder) {
final GifHeader header = parser.parseHeader();
if (header.getNumFrames() <= 0 || header.getStatus() != GifDecoder.STATUS_OK) {
// If we couldn't decode the GIF, we will end up with a frame count of 0.
return null;
}
Bitmap firstFrame = decodeFirstFrame(decoder, header, data);
if (firstFrame == null) {
return null;
}
Transformation<Bitmap> unitTransformation = UnitTransformation.get();
GifDrawable gifDrawable = new GifDrawable(context, provider, bitmapPool, unitTransformation, width, height,
header, data, firstFrame);
return new GifDrawableResource(gifDrawable);
}
private GifDecoder decodeHeaders(byte[] data) {
GifHeaderParser parser = factory.buildParser();
parser.setData(data);
GifHeader header = parser.parseHeader();
GifDecoder decoder = factory.buildDecoder(provider);
decoder.setData(header, data);
decoder.advance();
return decoder;
}
GifDrawable(GifState state) {
if (state == null) {
throw new NullPointerException("GifState must not be null");
}
this.state = state;
this.decoder = new GifDecoder(state.bitmapProvider);
this.paint = new Paint();
decoder.setData(state.gifHeader, state.data);
frameLoader = new GifFrameLoader(state.context, this, decoder, state.targetWidth, state.targetHeight);
frameLoader.setFrameTransformation(state.frameTransformation);
}
GifDrawable(GifDecoder decoder, GifFrameLoader frameLoader, Bitmap firstFrame, BitmapPool bitmapPool, Paint paint) {
this.decoder = decoder;
this.frameLoader = frameLoader;
this.state = new GifState(null);
this.paint = paint;
state.bitmapPool = bitmapPool;
state.firstFrame = firstFrame;
}
@Override
public GifDrawableResource decode(InputStream source, int width, int height) {
byte[] data = inputStreamToBytes(source);
final GifHeaderParser parser = parserPool.obtain(data);
final GifDecoder decoder = decoderPool.obtain(provider);
try {
return decode(data, width, height, parser, decoder);
} finally {
parserPool.release(parser);
decoderPool.release(decoder);
}
}
private void ensureGifHeader() {
if (mGifHeader != null) return;
GifHeaderParser parser = new GifHeaderParser();
parser.setData(getInputStreamData());
mGifHeader = parser.parseHeader();
parser.clear();
if (mGifHeader.getStatus() != GifDecoder.STATUS_OK) {
throw new RuntimeException("Illegal status: " + mGifHeader.getStatus());
}
}
private void ensureGifDecoder() {
if (mGifDecoder != null) return;
ensureGifHeader();
GifDecoder.BitmapProvider provider = new GifBitmapProvider(
Glide.get(mContext).getBitmapPool(),
Glide.get(mContext).getArrayPool()
);
mGifDecoder = new StandardGifDecoder(provider);
mGifDecoder.setData(mGifHeader, getInputStreamData());
mGifFrames = mGifDecoder.getFrameCount() + 1;
}
public GifFrameLoader(Context context, FrameCallback callback, GifDecoder gifDecoder, int width, int height) {
this(callback, gifDecoder, null,
getRequestBuilder(context, gifDecoder, width, height, Glide.get(context).getBitmapPool()));
}
@Override
public DataFetcher<GifDecoder> getResourceFetcher(GifDecoder model, int width, int height) {
return new GifFrameDataFetcher(model);
}
public GifFrameDataFetcher(GifDecoder decoder) {
this.decoder = decoder;
}
@Override
public GifDecoder loadData(Priority priority) {
return decoder;
}
@Override
public boolean encode(Resource<GifDrawable> resource, OutputStream os) {
long startTime = LogTime.getLogTime();
GifDrawable drawable = resource.get();
Transformation<Bitmap> transformation = drawable.getFrameTransformation();
if (transformation instanceof UnitTransformation) {
return writeDataDirect(drawable.getData(), os);
}
GifDecoder decoder = decodeHeaders(drawable.getData());
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();
}
}
boolean result = encoder.finish();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Encoded gif with " + decoder.getFrameCount() + " frames and " + drawable.getData().length
+ " bytes in " + LogTime.getElapsedMillis(startTime) + " ms");
}
return result;
}
public GifDecoder buildDecoder(GifDecoder.BitmapProvider bitmapProvider) {
return new GifDecoder(bitmapProvider);
}
public GifDecoder getDecoder() {
return decoder;
}
private Bitmap decodeFirstFrame(GifDecoder decoder, GifHeader header, byte[] data) {
decoder.setData(header, data);
decoder.advance();
return decoder.getNextFrame();
}
public synchronized void release(GifDecoder decoder) {
decoder.clear();
pool.offer(decoder);
}
@Override
public Resource<Bitmap> decode(GifDecoder source, int width, int height) {
Bitmap bitmap = source.getNextFrame();
return BitmapResource.obtain(bitmap, bitmapPool);
}
@Nullable
public static GlFilter createGlFilter(@NonNull Context context,
@NonNull Uri overlayUri,
@NonNull PointF size,
@NonNull PointF position,
float rotation) {
GlFilter filter = null;
try {
if (TextUtils.equals(context.getContentResolver().getType(overlayUri), "image/gif")) {
ContentResolver contentResolver = context.getApplicationContext().getContentResolver();
InputStream inputStream = contentResolver.openInputStream(overlayUri);
BitmapPool bitmapPool = new LruBitmapPool(10);
GifBitmapProvider gifBitmapProvider = new GifBitmapProvider(bitmapPool);
final GifDecoder gifDecoder = new StandardGifDecoder(gifBitmapProvider);
gifDecoder.read(inputStream, (int) TranscoderUtils.getSize(context, overlayUri));
AnimationFrameProvider animationFrameProvider = new AnimationFrameProvider() {
@Override
public int getFrameCount() {
return gifDecoder.getFrameCount();
}
@Nullable
@Override
public Bitmap getNextFrame() {
return gifDecoder.getNextFrame();
}
@Override
public long getNextFrameDurationNs() {
return TimeUnit.MILLISECONDS.toNanos(gifDecoder.getNextDelay());
}
@Override
public void advance() {
gifDecoder.advance();
}
};
filter = new FrameSequenceAnimationOverlayFilter(animationFrameProvider, size, position, rotation);
} else {
filter = new BitmapOverlayFilter(context.getApplicationContext(), overlayUri, size, position, rotation);
}
} catch (IOException ex) {
Log.e(TAG, "Failed to create a GlFilter", ex);
}
return filter;
}
/**
* Constructor for GifDrawable.
*
* @see #setFrameTransformation(Transformation, Bitmap)
*
* @param context A context.
* @param bitmapProvider An {@link GifDecoder.BitmapProvider} that can be used to
* retrieve re-usable {@link Bitmap}s.
* @param bitmapPool A {@link BitmapPool} that can be used to return
* the first frame when this drawable is recycled.
* @param frameTransformation An {@link Transformation} that can be applied to each frame.
* @param targetFrameWidth The desired width of the frames displayed by this drawable (the width of the view or
* {@link com.bumptech.glide.request.target.Target} this drawable is being loaded into).
* @param targetFrameHeight The desired height of the frames displayed by this drawable (the height of the view or
* {@link com.bumptech.glide.request.target.Target} this drawable is being loaded into).
* @param gifHeader The header data for this gif.
* @param data The full bytes of the gif.
* @param firstFrame The decoded and transformed first frame of this gif.
*/
public GifDrawable(Context context, GifDecoder.BitmapProvider bitmapProvider, BitmapPool bitmapPool,
Transformation<Bitmap> frameTransformation, int targetFrameWidth, int targetFrameHeight,
GifHeader gifHeader, byte[] data, Bitmap firstFrame) {
this(new GifState(gifHeader, data, context, frameTransformation, targetFrameWidth, targetFrameHeight,
bitmapProvider, bitmapPool, firstFrame));
}