android webp格式的图片,Android使用Glide加载SVG、Webp格式的图片

本文介绍如何在Android项目中使用Glide框架加载SVG、WebP等多种格式的图片,包括添加依赖、自定义Decoder和Transcoder,以及处理SVG的软解码。详细步骤包括添加Glide、SVG和WebP相关库的依赖,自定义SVG和WebP的Decoder、Transcoder,以及RequestListener。最后展示了加载不同格式图片的示例代码。
摘要由CSDN通过智能技术生成

项目中想使用一个框架实现常见的所有图片格式的加载,并且对代码的影响降到最低,Glide框架提供了很好的扩展,这里使用Glide+androidsvg+fresco实现加载GIF、SVG、WebP等多种格式的图片和动画文件。

实现原理

具体步骤

1、添加依赖

dependencies {

implementation 'com.github.bumptech.glide:glide:4.9.0'

annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'

implementation 'com.caverock:androidsvg-aar:1.3'

implementation "com.facebook.fresco:animated-webp:1.9.0"

}

2、SVG

1、自定义ResourceDecoder,将InputStream转为SVG对象:

import android.support.annotation.NonNull;

import com.bumptech.glide.load.Options;

import com.bumptech.glide.load.ResourceDecoder;

import com.bumptech.glide.load.engine.Resource;

import com.bumptech.glide.load.resource.SimpleResource;

import com.caverock.androidsvg.SVG;

import com.caverock.androidsvg.SVGParseException;

import java.io.IOException;

import java.io.InputStream;

/**

* Decodes an SVG internal representation from an {@link InputStream}.

*/

public class SvgDecoder implements ResourceDecoder {

@Override

public boolean handles(@NonNull InputStream source, @NonNull Options options) {

// TODO: Can we tell?

return true;

}

public Resource decode(@NonNull InputStream source, int width, int height,

@NonNull Options options)

throws IOException {

try {

SVG svg = SVG.getFromInputStream(source);

return new SimpleResource<>(svg);

} catch (SVGParseException ex) {

throw new IOException("Cannot load SVG from stream", ex);

}

}

}

2、自定义ResourceTranscoder,将SVG转为Drawable对象

import android.graphics.Picture;

import android.graphics.drawable.PictureDrawable;

import android.support.annotation.NonNull;

import android.support.annotation.Nullable;

import com.bumptech.glide.load.Options;

import com.bumptech.glide.load.engine.Resource;

import com.bumptech.glide.load.resource.SimpleResource;

import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;

import com.caverock.androidsvg.SVG;

/**

* Convert the {@link SVG}'s internal representation to an Android-compatible one

* ({@link Picture}).

*/

public class SvgDrawableTranscoder implements ResourceTranscoder {

@Nullable

@Override

public Resource transcode(@NonNull Resource toTranscode,

@NonNull Options options) {

SVG svg = toTranscode.get();

Picture picture = svg.renderToPicture();

PictureDrawable drawable = new PictureDrawable(picture);

return new SimpleResource<>(drawable);

}

}

3、SVG格式不能硬解码,自定义RequestListener,在onResourceReady时设置ImageView为软解码

import android.graphics.drawable.PictureDrawable;

import android.widget.ImageView;

import com.bumptech.glide.load.DataSource;

import com.bumptech.glide.load.engine.GlideException;

import com.bumptech.glide.request.RequestListener;

import com.bumptech.glide.request.target.ImageViewTarget;

import com.bumptech.glide.request.target.Target;

/**

* Listener which updates the {@link ImageView} to be software rendered, because

* {@link com.caverock.androidsvg.SVG SVG}/{@link android.graphics.Picture Picture} can't render on

* a hardware backed {@link android.graphics.Canvas Canvas}.

*/

public class SvgSoftwareLayerSetter implements RequestListener {

@Override

public boolean onLoadFailed(GlideException e, Object model, Target target,

boolean isFirstResource) {

ImageView view = ((ImageViewTarget>) target).getView();

view.setLayerType(ImageView.LAYER_TYPE_NONE, null);

return false;

}

@Override

public boolean onResourceReady(PictureDrawable resource, Object model,

Target target, DataSource dataSource, boolean isFirstResource) {

ImageView view = ((ImageViewTarget>) target).getView();

view.setLayerType(ImageView.LAYER_TYPE_SOFTWARE, null);

return false;

}

}

3、WebP

1、WebpFrameLoader,加载每帧图片

import android.graphics.Bitmap;

import android.os.Handler;

import android.os.Looper;

import android.os.Message;

import android.os.SystemClock;

import com.bumptech.glide.Glide;

import com.bumptech.glide.RequestBuilder;

import com.bumptech.glide.RequestManager;

import com.bumptech.glide.gifdecoder.GifDecoder;

import com.bumptech.glide.load.Key;

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.request.RequestOptions;

import com.bumptech.glide.request.target.SimpleTarget;

import com.bumptech.glide.request.transition.Transition;

import com.bumptech.glide.util.Preconditions;

import com.bumptech.glide.util.Util;

import java.nio.ByteBuffer;

import java.security.MessageDigest;

import java.util.ArrayList;

import java.util.List;

import java.util.UUID;

public class WebpFrameLoader {

final RequestManager requestManager;

private final GifDecoder gifDecoder;

private final Handler handler;

private final List callbacks;

private final BitmapPool bitmapPool;

private boolean isRunning;

private boolean isLoadPending;

private boolean startFromFirstFrame;

private RequestBuilder requestBuilder;

private DelayTarget current;

private boolean isCleared;

private DelayTarget next;

private Bitmap firstFrame;

private Transformation transformation;

public WebpFrameLoader(Glide glide, GifDecoder gifDecoder, int width, int height, Transformation transformation, Bitmap firstFrame) {

this(glide.getBitmapPool(), Glide.with(glide.getContext()), gifDecoder, null, getRequestBuilder(Glide.with(glide.getContext()), width, height), transformation, firstFrame);

}

WebpFrameLoader(BitmapPool bitmapPool, RequestManager requestManager, GifDecoder gifDecoder, Handler handler, RequestBuilder requestBuilder, Transformation transformation, Bitmap firstFrame) {

this.callbacks = new ArrayList();

this.isRunning = false;

this.isLoadPending = false;

this.startFromFirstFrame = false;

this.requestManager = requestManager;

if (handler == null) {

handler = new Handler(Looper.getMainLooper(), new FrameLoaderCallback());

}

this.bitmapPool = bitmapPool;

this.handler = handler;

this.requestBuilder = requestBuilder;

this.gifDecoder = gifDecoder;

this.setFrameTransformation(transformation, firstFrame);

}

private static RequestBuilder getRequestBuilder(RequestManager requestManager, int width, int height) {

return requestManager.asBitmap().apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.NONE).skipMemoryCache(true).override(width, height));

}

void setFrameTransformation(Transformation transformation, Bitmap firstFrame) {

this.transformation = Preconditions.checkNotNull(transformation);

this.firstFrame = Preconditions.checkNotNull(firstFrame);

this.requestBuilder = this.requestBuilder.apply((new RequestOptions()).transform(transformation));

}

Transformation getFrameTransformation() {

return this.transformation;

}

Bitmap getFirstFrame() {

return this.firstFrame;

}

void subscribe(FrameCallback frameCallback) {

if (this.isCleared) {

throw new IllegalStateException("Cannot subscribe to a cleared frame loader");

} else {

boolean start = this.callbacks.isEmpty();

if (this.callbacks.contains(frameCallback)) {

throw new IllegalStateException("Cannot subscribe twice in a row");

} else {

this.callbacks.add(frameCallback);

if (start) {

this.start();

}

}

}

}

void unsubscribe(FrameCallback frameCallback) {

this.callbacks.remove(frameCallback);

if (this.callbacks.isEmpty()) {

this.stop();

}

}

int getWidth() {

return this.getCurrentFrame().getWidth();

}

int getHeight() {

return this.getCurrentFrame().getHeight();

}

int getSize() {

return this.gifDecoder.getByteSize() + this.getFrameSize();

}

int getCurrentIndex() {

return this.current != null ? this.current.index : -1;

}

private int getFrameSize() {

return Util.getBitmapByteSize(this.getCurrentFrame().getWidth(), this.getCurrentFrame().getHeight(), t

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值