Fresco · 基本使用及Gif和webP播放及循环播放详解

Fresco · 基本使用及Gif和webP播放及循环播放详解

Facebook 出品的一个强大的图片加载组件
Fresco 是一个强大的图片加载组件。使用它之后,你不需要再去关心图片的加载和显示这些繁琐的事情! 支持 Android 2.3 及以后的版本。
这里我们要解决的问题在于当切图资源没有给webP加入循环播放的设置,这就要前端进行处理,实现自动播放webp格
式动图且循环播放。
有的同志就要拿着你的显示屏打我头了,那为什么不让UI或者原型将webp动图加入循环展示的设置呢?
那我就要拿着我8块钱地摊买的人字拖打回去了。这里我们说的时UI或者设计没有给这个样子的webp动图,我们前台该怎么去处理的问题。

github 地址
石原里美

特性
内存管理
  • 解压后的图片,即Android中的Bitmap,占用大量的内存。大的内存占用势必引发更加频繁的GC。在5.0以下,GC将会显著地引发界面卡顿。

  • 在5.0以下系统,Fresco将图片放到一个特别的内存区域。当然,在图片不显示的时候,占用的内存会自动被释放。这会使得APP更加流畅,减少因图片内存占用而引发的OOM。

  • Fresco 在低端机器上表现一样出色,你再也不用因图片内存占用而思前想后。

图片绘制

Fresco 的 Drawees 设计,带来一些有用的特性:

  • 自定义居中焦点
  • 圆角图,当然圆圈也行
  • 下载失败之后,点击重现下载
  • 自定义占位图,自定义overlay, 或者进度条
  • 指定用户按压时的overlay

图片加载

圆角图片 圆形图片 快速配置

Fresco的 Image Pipeline 允许你用很多种方式来自定义图片加载过程,比如:

为同一个图片指定不同的远程路径,或者使用已经存在本地缓存中的图片
先显示一个低清晰度的图片,等高清图下载完之后再显示高清图
加载完成回调通知
对于本地图,如有EXIF缩略图,在大图加载完成之前,可先显示缩略图
缩放或者旋转图片
对已下载的图片再次处理
支持WebP解码,即使在早先对WebP支持不完善的Android系统上也能正常使用!


图片的渐进式呈现
渐进式的JPEG图片格式已经流行数年了,渐进式图片格式先呈现大致的图片轮廓,
然后随着图片下载的继续,呈现逐渐清晰的图片,这对于移动设备,尤其是慢网络有极大的利好,可带来更好的用户体验。      

Android 本身的图片库不支持此格式,但是Fresco支持。使用时,和往常一样,
仅仅需要提供一个图片的URI即可,剩下的事情,Fresco会处理。


动图加载

加载 Gif 图和 WebP 动图在任何一个Android开发者眼里看来都是一件非常头疼的事情。每一帧都是一张很大的Bitmap,每一个动画都有很多帧。Fresco让你没有这些烦恼,它处理好每一帧并管理好你的内存


I.基本使用
GIF格式图片

DraweeController controller = Fresco.newDraweeControllerBuilder()
                .setUri(uri)//设置资源地址
                .setAutoPlayAnimations(true)//设置是否自动播放
                .build();
        simpleDraweeView.setController(controller);
引入框架

官方文档引入版本

dependencies {
  // 在 API < 14 上的机器支持 WebP 时,需要添加
  compile 'com.facebook.fresco:animated-base-support:0.12.0'

  // 支持 GIF 动图,需要添加
  compile 'com.facebook.fresco:animated-gif:0.12.0'

  // 支持 WebP (静态图+动图),需要添加
  compile 'com.facebook.fresco:animated-webp:0.12.0'
  compile 'com.facebook.fresco:webpsupport:0.12.0'

  // 仅支持 WebP 静态图,需要添加
  compile 'com.facebook.fresco:webpsupport:0.12.0'
}

注意:官网引入的版本知识作为引入及使用示范,目前位置陆陆续续发布了许多新版本,项目使用上,尽量使用尽可能的新版本。
这里博客中使用的**1.9.0**版本,其中修复了以前的内存泄漏或者图片处理上的问题,优化了和减少了代码上的冗余等,

dependencies {
	 //必须添加
    implementation 'com.facebook.fresco:fresco:1.9.0'
    //依需要添加
    // For animated GIF support
    implementation 'com.facebook.fresco:animated-gif:1.9.0'
    // For WebP support, including animated WebP
    implementation 'com.facebook.fresco:animated-webp:1.9.0'
    implementation 'com.facebook.fresco:webpsupport:1.9.0'
    // For WebP support, without animations
    implementation 'com.facebook.fresco:webpsupport:1.9.0'
    // Provide the Android support library (you might already have this or a similar dependency)
    implementation 'com.android.support:support-core-utils:28.0.0'
}

引入资源
URI引入支持的类型
类型Scheme示例
远程图片http://,https:// ,两种协议同时支持HttpURLConnection 或者参考 使用其他网络加载方案OkHttp 是一个流行的开源网络请求库,使用广泛的是Retrofit2网络框架(依照实际情况结合力选择)
本地文件file://FileInputStream
Contentprovidercontent://ContentResolver
asset目录下的资源asset://AssetManager
res目录下的资源res://Resources.openRawResource
Uri中指定图片数据data:mime/type;base64数据类型必须符合 rfc2397规定 (仅支持 UTF-8)

初始化

Application的继承类中的Oncreate();方法中初始化

Fresco.initialize(this);


使用
XML(布局文件)中使用

注意:SimpleDraweeView必须指定确定大小,不支持wrap_content
res 示例:

Uri uri = Uri.parse("res://包名(实际可以是任何字符串甚至留空)/" + R.drawable.ic_launcher);
  • 只有图片资源才能使用在Image pipeline中,比如(PNG)。其他资源类型,比如字符串,或者XML Drawable在Image pipeline中没有意义。所以加载的资源不支持这些类型。
  • 像ShapeDrawable这样声明在XML中的drawable可能引起困惑。注意到这毕竟不是图片。如果想把这样的drawable作为图像显示,那么把这个drawable设置为占位图,然后把URI设置为null。

fresco声明: xmlns:fresco="http://schemas.android.com/apk/res-auto

<android.support.constraint.ConstraintLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fresco="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_blue_light">
	<com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="280dp"
        android:layout_marginStart="67dp"
        android:layout_marginLeft="67dp"
        android:layout_marginEnd="67dp"
        android:layout_marginRight="67dp"
        android:layout_marginBottom="123dp"
        fresco:layout_constraintBottom_toBottomOf="parent"
        fresco:layout_constraintEnd_toEndOf="parent"
        fresco:layout_constraintStart_toStartOf="parent"
        fresco:placeholderImage="@drawable/ic_launcher_background" />
</android.support.constraint.ConstraintLayout>


简单加载网络图片
Uri uri = Uri.parse("https://raw.githubusercontent.com/facebook/fresco/gh-pages/static/logo.png");
SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view);
draweeView.setImageURI(uri);

SimpleDraweeView配置示例
<com.facebook.drawee.view.SimpleDraweeView
  android:id="@+id/my_image_view"
  android:layout_width="20dp"
  android:layout_height="20dp"
  fresco:fadeDuration="300"
  fresco:actualImageScaleType="focusCrop"
  fresco:placeholderImage="@color/wait_color"
  fresco:placeholderImageScaleType="fitCenter"
  fresco:failureImage="@drawable/error"
  fresco:failureImageScaleType="centerInside"
  fresco:retryImage="@drawable/retrying"
  fresco:retryImageScaleType="centerCrop"
  fresco:progressBarImage="@drawable/progress_bar"
  fresco:progressBarImageScaleType="centerInside"
  fresco:progressBarAutoRotateInterval="1000"
  fresco:backgroundImage="@color/blue"
  fresco:overlayImage="@drawable/watermark"
  fresco:pressedStateOverlayImage="@color/red"
  fresco:roundAsCircle="false"
  fresco:roundedCornerRadius="1dp"
  fresco:roundTopLeft="true"
  fresco:roundTopRight="false"
  fresco:roundBottomLeft="false"
  fresco:roundBottomRight="true"
  fresco:roundWithOverlayColor="@color/corner_color"
  fresco:roundingBorderWidth="2dp"
  fresco:roundingBorderColor="@color/border_color"
/>
各种使用详解

在xml中使用
在java中使用
Drawee的各种效果配置
进度条
缩放
圆角和圆圈
使用ControllerBuilder
渐进式JPEG图
动画支持
多图请求及图片复用
监听下载事件
缩放和旋转图片
修改图片
图片请求(Image Requests)
自定义View

Image Pipeline

Image Pipeline介绍
Image pipeline 负责完成加载图像,变成Android设备可呈现的形式所要做的每个事情。
流程如下:

  • 检查内存缓存,如有,返回
  • 后台线程开始后续工作
  • 检查是否在未解码内存缓存中。如有,解码,变换,返回,然后缓存到内存缓存中。
  • 检查是否在磁盘缓存中,如果有,变换,返回。缓存到未解码缓存和内存缓存中。
  • 从网络或者本地加载。加载完成后,解码,变换,返回。存到各个缓存中。

既然本身就是一个图片加载组件,那么一图胜千言。

IMAG PIPEELINE


1. 上图中,disk cache实际包含了未解码的内存缓存在内,统一在一起只是为了逻辑稍微清楚一些。关于缓存,更多细节可以参考这里。
Image pipeline 可以从本地加载图片,也可以从网络。支持 PNGGIFWebP, JPEG

2.各个Android系统的WebP适配
在Android 3.0系统之前,Android是不支持 WebP格式的。在4.1.2之前,扩展WebP格式是不支持的。 在Image pipeline的支持下,从2.3之后,都可以使用WebP格式。


GIF动图加载与WebP动图加载

1.GIF图片加载

将setAutoPlayAnimations();值为true

  • 实现自动播放
  • 实现循环播放
Uri uri = Uri.parse("http://img.soogif.com/qaDs69glJi2ojoMMJCDAocDvyIQlwfaN.gif");
DraweeController controller = Fresco.newDraweeControllerBuilder()
              .setUri(uri)//设置资源地址
              .setAutoPlayAnimations(true)//设置是否自动播放
              .build();
simpleDraweeView.setController(controller);

目前 支持 webp 动图 的 三方图片库,只有Fresco,想控制 动图 播放 和 暂停 的 也只有 Fresco
(声明:其他的三方库也都用过,只不过本文的功能 目前只有 Fresco 能简单实现)

2.webP格式的动图循环自动播放

http://voddafz06jj.vod.126.net/voddafz06jj/videoPreview_1821338293_IQAB9DSR.webp
这是 .webp 动图地址

  Uri uri = Uri.parse("http://voddafz06jj.vod.126.net/voddafz06jj/videoPreview_1821338293_IQAB9DSR.webp");
   DraweeController controller = Fresco.newDraweeControllerBuilder()
                .setUri(uri)//设置资源地址
                .setAutoPlayAnimations(true)//设置是否自动播放
                .build();
  simpleDraweeView.setController(controller);

图片示例: webP格式动图自动播放但不循环播放
自动播放但不循环

对应GIF的自动循环播放方式就不适用于webP格式的动图。那么如何做?

注意:
同时还要设置.setAutoPlayAnimations(true)


//DraweeController 
 Uri uri = Uri.parse("http://voddafz06jj.vod.126.net/voddafz06jj/videoPreview_1821338293_IQAB9DSR.webp");
 final DraweeController controller = Fresco.newDraweeControllerBuilder()
                .setAutoPlayAnimations(true)
                .setUri(uri)
                .setControllerListener(new BaseControllerListener<ImageInfo>() {
                    @Override
                    public void onFinalImageSet(
                            String id,
                            @Nullable ImageInfo imageInfo,
                            @Nullable Animatable animatable) {
                        if (animatable instanceof AnimatedDrawable2) {
                            AnimatedDrawable2 animatedDrawable = (AnimatedDrawable2) animatable;
                            animatedDrawable.setAnimationBackend(new LoopCountModifyingBackend(animatedDrawable.getAnimationBackend(), 1000));//设置循环次数
                        }
                    }
                })
                .build();

 simpleDraweeView.setController(controller);



//LoopCountModifyingBackend
public class LoopCountModifyingBackend extends AnimationBackendDelegate {
	private int mLoopCount;
	public LoopCountModifyingBackend(@Nullable AnimationBackend animationBackend,int loopCount) {
            super(animationBackend);
            mLoopCount = loopCount;
    }

    @Override
    public int getLoopCount() {
        return mLoopCount;
    }
}


图片示例: webP格式动图自动播放且循环播放

自动播放且循环播放

【提供好的可自动循环播放的webp动图】
https://isparta.github.io/compare-webp/image/gif_webp/webp/1.webp

【提供的无循环播放的webp动图】
http://voddafz06jj.vod.126.net/voddafz06jj/videoPreview_1821338293_IQAB9DSR.webp


推荐资源


sifi


[1]从零开始撸一个Fresco之gif和Webp动画
[2]Fresco官文
[3]GIF/PNG/JPG和WEBP/base64/apng图片优点和缺点整理
[4]Glide官文
[5] Glide(Github)
[6]网络加载图片对比(Fresco/Glide)


转载请注明出处

作者: maiduoduo
邮箱: maiduoduo0@163.com
博客主页: https://blog.csdn.net/Maiduoudo

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Android官方的ImageView控件并不支持直接加载GIF动画,但是可以通过使用第三方库来实现在XML布局中显示GIF动画的效果。 目前比较常用的第三方库有: 1. Glide:Glide是一个功能强大、灵活且易于使用的图片加载库,支持GIF动画的加载和显示。 2. FrescoFresco是Facebook开源的一个功能强大、灵活且易于使用的图片加载库,支持GIF动画的加载和显示。 下面以Glide为例,演示如何在XML布局中显示GIF动画: 1.在build.gradle文件中添加依赖: ``` dependencies { implementation 'com.github.bumptech.glide:glide:4.12.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' } ``` 2.在XML布局文件中使用如下代码: ``` <com.bumptech.glide.load.resource.gif.GifDrawableImageView android:id="@+id/iv_gif" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/my_gif"/> ``` 其中,com.bumptech.glide.load.resource.gif.GifDrawableImageView是Glide库自带的一个支持GIF动画的ImageView控件。 3.在Java代码中使用如下代码: ``` ImageView imageView = findViewById(R.id.iv_gif); Glide.with(this).asGif().load(R.drawable.my_gif).into(imageView); ``` 其中,asGif()方法表示要加载的是GIF动画,R.drawable.my_gif是要加载的GIF动画资源ID。 需要注意的是,使用Glide加载GIF动画时,需要添加asGif()方法来告诉Glide要加载的是GIF动画,否则默认情况下会当作静态图片处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值