转载请注明转自http://write.blog.csdn.net/postedit/50459154【小曾的博客】

关于 Fresco

Fresco 是一个强大的图片加载组件。

Fresco 中设计有一个叫做 image pipeline 的模块。它负责从网络,从本地文件系统,本地资源加载图片。为了最大限度节省空间和CPU时间,它含有3级缓存设计(2级内存,1级文件)。

Fresco 中设计有一个叫做 Drawees 模块,方便地显示loading图,当图片不再显示在屏幕上时,及时地释放内存和空间占用。

Fresco 支持 Android2.3(API level 9) 及其以上系统。

    MVC模式

现在听好多人都在谈设计模式一些MVC和MVP等设计模式,然后DraweeView也是MVC模式的。

  1. View 对应DraweeView类(实际上是DraweeHolder),其负责展示数据,显示图片。
  2. Model对应DraweeHierarchy类,其负责持有数据,用一个层级组织和维护最终绘制和显示的图片。
  3. Controller对应DraweeController类,其负责控制数据的逻辑。

文字略显苍白,图片才是最好的诠释方式,其中代码是示意使用后续会分析到。如图:

DraweeView-DraweeHierarchy-DraweeController关系

在Fresco的框架中,DraweeView背后的DraweeHolder持有了DraweeHierarchyDraweeController两个类的引用。SimpleDraweeView使用setImageUri()方法发出要显示图片的请求。

随后,通过一系列的操作去构造DraweeController的实例以便发出请求和更新视图。然后,马上使用setController()方法以及setHierarchy()方法,通知DraweeView视图的改变以显示加载效果(此时还是图片请求过程中)。

最后,通过DraweeController请求成功的回调,再次通知DraweeHierarchy视图改变,以完成显示图片的全部操作。

其实文档说的很清楚了怎么使用Fresco,但是要学习就得自己去实践

使用Fresco

1.先去 GitHub上下载Fresco

$gitclone https://github.com/facebook/fresco.git

2.第二步添加Fresco到项目工程:

不解释直接加到build.gradle里面:

compile'com.facebook.fresco:fresco:0.7.0+'

然后就是一段时间的下载,也是够了

官方文档已经说fresco的类库发布到了Maven中央库,所以我们只需添加上面的代码配置再同步编译即可

repositories {
    jcenter()
    mavenCentral()
}

下面我们就来实践使用咯。既然要看网络加载图片,那我们必须在清单文件里面加网络访问权限

现在我们来使用一下SimpleDraweeView

XML属性 意义
fadeDuration 淡入淡出动画持续时间(单位:毫秒ms)
actualImageScaleType 实际图像的缩放类型
placeholderImage 占位图
placeholderImageScaleType 占位图的缩放类型
progressBarImage 进度图
progressBarImageScaleType 进度图的缩放类型
progressBarAutoRotateInterval 进度图自动旋转间隔时间(单位:毫秒ms)
failureImage 失败图
failureImageScaleType 失败图的缩放类型
retryImage 重试图
retryImageScaleType 重试图的缩放类型
backgroundImage 背景图
overlayImage 叠加图
pressedStateOverlayImage 按压状态下所显示的叠加图
roundAsCircle 设置为圆形图
roundedCornerRadius 圆角半径
roundTopLeft 左上角是否为圆角
roundTopRight 右上角是否为圆角
roundBottomLeft 左下角是否为圆角
roundBottomRight 右下角是否为圆角
roundingBorderWidth 圆形或者圆角图边框的宽度
roundingBorderColor 圆形或者圆角图边框的颜色
roundWithOverlayColor 圆形或者圆角图底下的叠加颜色(只能设置颜色)
viewAspectRatio 控件纵横比

把上面的属性用好了,一般的效果就能轻松搞出来了,不解释,其实那么多内容也就是搞清楚这张表。

先使用本地占位图片:placeholderImage设置圆圈:roundAsCircle 设置圆弧角度:roundedCornerRadius

麻麻再也不用担心我写不出圆形图片了

<com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/icon1"
    android:layout_width="50dp"
    android:layout_height="50dp"
    fresco:roundAsCircle="true"
    fresco:roundedCornerRadius="180dp"
    fresco:actualImageScaleType="focusCrop"
    fresco:placeholderImage="@mipmap/alipay"
    fresco:placeholderImageScaleType="fitCenter"
  />

大家可能看到,属性中存在fresco:开头的声明。

<RelativeLayout
    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"
    >

这个是fresco的自定义属性,如果我们需要使用其自定义属性,必须在我们的xml根布局中添加声明/命名空间,上图蓝色部分

然后在代码中自需要初始化就好了:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Fresco.initialize(this);
    setContentView(R.layout.activity_main);
}

切记 Fresco.initialize(this);必须放在设置布局的前面,而且不写还不行,不要问我为什么,哥也不知道。

看效果图:

圆形图片就是这样轻松的出来了,感觉心里有点小激动。

然后我们来个圆角图片:

<com.facebook.drawee.view.SimpleDraweeView
     android:layout_marginLeft="100dp"
     android:layout_width="50dp"
     android:layout_height="50dp"
     fresco:roundAsCircle="false"
    fresco:roundedCornerRadius="5dp"
     fresco:actualImageScaleType="focusCrop"
     fresco:placeholderImage="@mipmap/alipay"
     fresco:placeholderImageScaleType="fitCenter"
     android:layout_centerVertical="true"
     />

接下来我们代码来实现圆角图片:

创建时设置

RoundingParams roundingParams = new RoundingParams();
roundingParams.setCornersRadius(mContext.getResources().getDimensionPixelOffset(R.dimen.sound_category_item_radius));
GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(mContext.getResources());
GenericDraweeHierarchy hierarchy = builder.build();
hierarchy.setRoundingParams(roundingParams);
mCategoryCoverIv.setHierarchy(hierarchy);

运行时修改

RoundingParams roundingParams = simpleDraweeView.getHierarchy().getRoundingParams();
roundingParams.setBorder(R.color.red, 1.0);
roundingParams.setRoundAsCircle(true);
simpleDraweeView.getHierarchy().setRoundingParams(roundingParams);

1、设置圆角时,支持4个角不同的半径。XML中无法配置,但可在Java代码中配置。
2、在运行时,不能改变呈现方式: 原本是圆角,不能改为圆圈。
3、并非所有的图片分支部分都可以实现圆角,目前只有占位图片和实际图片可以实现圆角,正在努力为背景图片实现圆角功能。
4、只有BitmapDrawable 和 ColorDrawable类的图片可以实现圆角。我们目前不支持包括NinePatchDrawable和 ShapeDrawable在内的其他类型图片。(无论他们是在XML或是程序中声明的)
5、动画不能实现圆角
6、由于Android的BitmapShader的限制,当一个图片不能覆盖全部的View的时候,边缘部分会被重复显示,而非留白。对这种情况可以使用不同的缩放类型(比如centerCrop)来保证图片覆盖了全部的View。

四个角不同半径实现

RoundingParams roundingParams = new RoundingParams();
roundingParams.setCornersRadii(10, 20, 30, 40);
GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(mContext.getResources());
GenericDraweeHierarchy hierarchy = builder.build();
hierarchy.setRoundingParams(roundingParams);
viewHolder.mCategoryCoverIv.setHierarchy(hierarchy);

然而用xml却不能实现,醉了,xml 是通过叠加一个solid color来绘制圆角。但是背景需要固定成指定的颜色。 在XML中指定 roundWithOverlayColor, 或者通过调用setOverlayColor来完成此设定。

对于同一个View,请不要多次调用setHierarchy,即使这个View是可回收的。创建 DraweeHierarchy 的较为耗时的一个过程,应该多次利用。

如果要改变所要显示的图片可使用setController 或者 setImageURI

接下来我们代码来实现加载网络图片:

先布局我们也不设置加载成功,加载失败图片和占位图:

<com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/icon1"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:layout_centerInParent="true"
    fresco:actualImageScaleType="focusCrop"
  />

然后 在代码中具体的使用:

private void initView() {
    //创建SimpleDraweeView对象
    simpleDraweeView = (SimpleDraweeView) findViewById(R.id.icon1);
    //创建将要下载的图片的URI
    Uri imageUri = Uri.parse("https://img-my.csdn.net/uploads/201407/26/1406383243_5120.jpg");
    //开始下载
    simpleDraweeView.setImageURI(imageUri);
}

神奇的事情出现了:

由于没有设置加载过程的图片,所以感觉不是很友好,像是等了很久,最后还是出现图片了(还以为不行呢)

然后我们还可以改变图片的大小,避免内存溢出:

/**
 * 显示缩略图(把原始图片变小)
 */
public  void showThumb(){
    //创建SimpleDraweeView对象
    simpleDraweeView = (SimpleDraweeView) findViewById(R.id.icon1);
    //创建将要下载的图片的URI
    Uri imageUri = Uri.parse("https://img-my.csdn.net/uploads/201407/26/1406383243_5120.jpg");
    ImageRequest request = ImageRequestBuilder.newBuilderWithSource(imageUri)
            .setResizeOptions(new ResizeOptions(dip2px(this, 80), dip2px(this, 80)))
            .build();
    DraweeController controller = Fresco.newDraweeControllerBuilder()
            .setImageRequest(request)
            .setOldController(simpleDraweeView.getController())
            .setControllerListener(new BaseControllerListener<ImageInfo>())
            .build();
    simpleDraweeView.setController(controller);
}
/**
 * dp 转像素
 * @param context
 * @param dpValue
 * @return
 */
private  int dip2px(Context context, float dpValue) {
    final float scale = context.getResources().getDisplayMetrics().density;
    int value=(int) (dpValue * scale + 0.5f);
    return value;
}

这里还要特别注意的是:出问题了 看官方文档 Resizing

此方法 只支持JPG, 只支持JPG, 只支持JPG, 草,

ImagePipelineConfig config = ImagePipelineConfig.newBuilder(this)     .setDownsampleEnabled(true)        .build();Fresco.initialize(this, config);

在初始化的时候这样写就可以支持Png什么的了。

 如果你懒, 那么,当你出现问题,有几个地方你得去瞅瞅咯:

Fresco Issue 567          这里有一些PNG图片展示的TooManyBitmapsException,
Fresco Issue 84              可以参考看看评论中解决问题的过程
Fresco Issue 738           不知道怎么设置缓存?可作参考

是不是感觉github就是程序员的天堂,牛逼可不可以这样吹

自动旋转
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri).setAutoRotateEnabled

(true).build();

好了那些什么网络加载过程中的加载成功失败图片的效果就不演示了。

缩放编辑和纠错

对于 Drawee 的各种效果配置,其中一些是支持缩放类型的。

可用的缩放类型

类型 描述
center 居中,无缩放。
centerCrop 保持宽高比缩小或放大,使得两边都大于或等于显示边界,且宽或高契合显示边界。居中显示。
focusCrop 同centerCrop, 但居中点不是中点,而是指定的某个点。
centerInside 缩放图片使两边都在显示边界内,居中显示。和 fitCenter 不同,不会对图片进行放大。
如果图尺寸大于显示边界,则保持长宽比缩小图片。
fitCenter 保持宽高比,缩小或者放大,使得图片完全显示在显示边界内,且宽或高契合显示边界。居中显示。
fitStart 同上。但不居中,和显示边界左上对齐。
fitEnd 同fitCenter, 但不居中,和显示边界右下对齐。
fitXY 不保存宽高比,填充满显示边界。
none 如要使用tile mode显示, 需要设置为none

这些缩放类型和Android ImageView 支持的缩放类型几乎一样.

唯一不支持的缩放类型是 matrix。Fresco 提供了 focusCrop 作为补充,通常这个使用效果更佳。

怎样设置

实际图片,占位图,重试图和失败图都可以在 xml 中进行设置,用fresco:actualImageScaleType 这样的属性。你也可以使用 GenericDraweeHierarchyBuilder 类在代码中进行设置。 即使显示效果已经构建完成,实际图片的缩放类型仍然可以通过GenericDraweeHierarchy 类在运行中进行修改。 不要使用 android:scaleType 属性,也不要使用setScaleType() 方法,它们对 Drawees 无效。

focusCrop

centerCrop缩放模式会保持长宽比,放大或缩小图片,填充满显示边界,居中显示。这个缩放模式在通常情况下很有用。

但是对于人脸等图片时,一味地居中显示,这个模式可能会裁剪掉一些有用的信息。

以人脸图片为例,借助一些类库,我们可以识别出人脸所在位置。如果可以设置以人脸位置居中裁剪显示,那么效果会好很多。

Fresco的focusCrop缩放模式正是为此而设计。只要提供一个居中聚焦点,显示时就会尽量以此点为中心。

居中点是以相对方式给出的,比如 (0f, 0f) 是左上对齐显示,(1f, 1f) 是右下角对齐。相对坐标使得居中点位置和具体尺寸无关,这是非常实用的。

(0.5f, 0.5f) 的居中点位置和缩放类型 centerCrop 是等价的。

如果要使用此缩放模式,首先在 XML 中指定缩放模式:

  fresco:actualImageScaleType="focusCrop"

在Java代码中,给你的图片指定居中点:

PointF focusPoint;
// your app populates the focus point
mSimpleDraweeView.getHierarchy().setActualImageFocusPoint(focusPoint);

none#

如果你要使用tile mode进行显示,那么需要将scale type 设置为none.

更多的效果和属性请自行去看:http://fresco-cn.org/docs/getting-started.html(里面有详细的介绍,个人感觉很不错的中文文档,麻麻再也不需要担心我的英语了)

你也可以去看下http://blog.csdn.net/y1scp/article/details/49245535,里面或许有你想要的效果额,累了睡觉了,这东西也是看到了,听说性能是相当的不错:

Fresco调研与性能测试

这里我们采用Picasso来与Fresco进行比较。(这里参考http://www.jianshu.com/p/d0b001bfa1a4)

上下滑动列表,观察应用的Java Heap和Native Heap的大小

Picasso

Fresco 

可以看到,使用Picasso的,其Java heap高达38M。而Fresco则将其控制在了10M以内。极大的减小了OOM的风险。

不过Native Heap占用很吓人,80MB。

那么使用ADB去查看一下内存:

Picasso时的内存

Fresco时的内存 

可以看到Fresco的Native Heap大小的确是70M,不过只占用了15M左右。而Fresco的Dalvik Heap占用为不到9M,是Picasso的四分之一还少,总共内存占用只有24M,是Picasso的一半左右。

实在要睡觉了,写个博客真的好累,有什么好的对Fresco的详解可以回复我,让我也多去学习一下,没有时间去看源码,那就学习别人的东西咯。

精彩文章链接:Fresco图片框架内部实现原理探索

Android图片处理之Fresco初实践相关推荐

  1. Android图片海报制作软件开发实践

    Android图片海报制作软件开发实践 项目地址:https://github.com/coolstar1204/MakePoster 本博客分以下几个文章,从头记录我学习Material Desig ...

  2. Android图片缓存框架 - Fresco的GenericDraweeHierarchy (五)

    目录 1.Fresco 简介 2. Fresco 文档 3. Fresco开发步骤 4. Fresco加载图片6种方式 5. Drawees xm属性设置 6 Fresco实现圆角或圆形图片 7. D ...

  3. Android图片缓存框架 - Fresco实现圆角或圆形图片 (四)

    目录 1.Fresco 简介 2. Fresco 文档 3. Fresco开发步骤 4. Fresco加载图片6种方式 5. Drawees xm属性设置 6 Fresco实现圆角或圆形图片 6.1 ...

  4. FaceBook推出的Android图片载入库-Fresco

    欢迎关注ndroid-tech-frontier开源项目,定期翻译国外Android优质的技术.开源库.软件架构设计.測试等文章 原文链接:Introducing Fresco: A new imag ...

  5. Android图片加载神器之Fresco-加载图片基础[详细图解Fresco的使用]

    前半部分找不到原文链接了 后半部分原文链接:http://www.jianshu.com/p/5364957dcf49 著作权归作者所有,转载请联系作者获得授权,并标注"简书作者" ...

  6. Android图片加载神器之Fresco-加载图片基础[详细图解Fresco的使用](秒杀imageloader)...

    Fresco简单的使用-SimpleDraweeView 百学须先立志-学前须知: 在我们平时加载图片(不管是下载还是加载本地图片-..)的时候,我们经常会遇到这样一个需求,那就是当图片正在加载时应该 ...

  7. android图片框架对比(全)ImageLoader、Picasso、Glide、Fresco、Coil

    一.直接表格对比 红色代表严重缺点 对比项 ImageLoader Picasso Glide Fresco Coil 库是否维护 false true true true true 是否支持gif ...

  8. fackbook的Fresco (FaceBook推出的Android图片加载库-Fresco)

    [Android开发经验]FaceBook推出的Android图片加载库-Fresco 欢迎关注ndroid-tech-frontier开源项目,定期翻译国外Android优质的技术.开源库.软件架构 ...

  9. android图片系统解决方案-从采集到显示

    概述 Android上图片涉及到的要点: 基础 自定义相机拍照 调用系统相机拍照 图片选择 裁剪 压缩 上传 服务端处理与下载 显示与内存-普通图与超大图 文件夹管理 内置图片管理与包大小 基础 颜色 ...

最新文章

  1. BST(binary search tree)类型题目需要用到的头文件binary_tree.h
  2. ASP.NET Core 2.1带来SignalR、Razor类库
  3. php获取http头信息,php如何获取http头信息
  4. ffmpeg rtmp 不清晰_知识储备:理解RTMP、HttpFlv和HLS的正确姿势
  5. ELF Format 笔记(七)—— 符号表
  6. 即将到来的 ECMAScript 2022 新特性
  7. SQLite数据库浅谈
  8. 不会延期!iPhone 12S预计如期在9月发售:升级三星LTPO屏幕
  9. 50、多线程创建的三种方式之实现Runnable接口
  10. 代码管理学:域名、产品名、应用名等都不是你能决定的,要上报备案
  11. linux仿win7软件,Ubuntu/Linux Mint用上仿Win7/Win8主题
  12. fatal: ‘http://git.#####.com/test-auto/stability.git/‘ 鉴权失败
  13. 雷达图使用攻略(上)
  14. 计算机网络中网关、路由器、网桥、交换机概念详解
  15. Filebeat Filter - Dissect/DNS Reverse
  16. 读到哪句你心痛了??
  17. win10计算机中删除桌面,win10系统电脑桌面壁纸历史记录怎么删除
  18. cocos2d 3.3 lua 代码加密 luac
  19. 「数据游戏」:使用 ARIMA 算法预测三日后招商银行收盘价
  20. win8通过u盘装linux系统,如何通过U盘装机大师进行U盘安装win8.1系统

热门文章

  1. 攒口水,吊仙气,且行且珍惜!
  2. Unity帧率的计算和显示
  3. 基于 Traefik 的激进 TLS 安全配置实践
  4. 计算机二级本科免修,计算机二级证书可以免考自考的哪些科目?
  5. 看图识数辨大小,人类独有的“数字感”被机器无意中学习了
  6. 用vue去实现百度下拉菜单
  7. 机器视觉与计算机视觉的区别与联系
  8. CentOS7下使用rpm安装RabbitMQ
  9. defaultChecked 和 checked 的区别
  10. 云原生 + 无代码,「DaoCloud 道客」探索无限可能——「DaoCloud 道客」+轻流联合解决方案