一、概述
Fressco是Facebook出品的优秀的图片加载框架,主要优点:
1、两个内存缓存加上 Native 缓存构成了三级缓存
2、支持流式,可以类似网页上模糊渐进式显示图片
3、对多帧动画图片支持更好,如 Gif、WebP
Picasso,Glide,Fresco基本项对比
对比项 | Picasso | Glide | Fresco |
---|---|---|---|
地址 | https://github.com/square/picasso | https://github.com/bumptech/glide | https://github.com/facebook/fresco |
发布时间 | 2013年5月 | 2014年9月 | 2015年5月 |
是否支持gif | false | true | true |
是否支持webP | true | true | true |
视频缩略图 | false | true | true |
大小 | 100k | 500 KB | 2~3M |
加载速度 | 中 | 高 | 高 |
Disk+Men Cache | true | true | true |
Easy of use | low | mediun | difficult |
star | 13160 | 14709 | 12444 |
开发者 | Square主导 | Google主导 | Facebook主导 |
二、使用
1、加入依赖
implementation 'com.facebook.fresco:fresco:2.3.0'
2、初始化(Application中初始化)
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Fresco.initialize(this);
}
}
3、添加布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/mSimpleDraweeView"
android:layout_width="match_parent"
android:layout_height="360dp" />
</LinearLayout>
常用XML属性
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/id_main_sdv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
fresco:actualImageScaleType="focusCrop" //加载得到的图片的缩放类型
fresco:fadeDuration="1000" //进度条,占位图片消失,加载图片展现的时间间隔
fresco:failureImage="@drawable/imgbg" //加载失败之后显示的图片
fresco:failureImageScaleType="centerInside" //图片缩放类型
fresco:placeholderImage="@drawable/imgbg" //占位图片(未加载之前显示的图片)
fresco:placeholderImageScaleType="fitCenter"
fresco:progressBarAutoRotateInterval="1000" //加载进度条图片旋转周期
fresco:progressBarImage="@drawable/progress_bar" //加载进度条图片
fresco:progressBarImageScaleType="centerInside"
fresco:retryImage="@mipmap/ic_launcher" //提示重新加载的图片资源
fresco:retryImageScaleType="centerCrop"
fresco:backgroundImage="@color/colorWhite" //背景图片
fresco:roundAsCircle="false" //是否要将图片剪切成圆形
fresco:viewAspectRatio="1" //图片宽高比
fresco:overlayImage="@drawable/overlay" //在图片上方覆盖一个图片资源
fresco:pressedStateOverlayImage="@color/colorBlack"
fresco:roundedCornerRadius="20dp" //圆角角度,
fresco:roundTopLeft="true" //设置哪个角需要变成圆角
fresco:roundTopRight="false"
fresco:roundBottomLeft="false"
fresco:roundBottomRight="true"
fresco:roundWithOverlayColor="@color/colorWhite" //圆角部分填充色
fresco:roundingBorderWidth="2dp" //边框宽度
fresco:roundingBorderColor="@color/colorBlack" //边框填充色
/>
上面的属性可以换成java代码实现
//新建一个DraweeHierarchyBuilder类
GenericDraweeHierarchyBuilder builder =new GenericDraweeHierarchyBuilder(getResources());
//设置的到图片的缩放类型
builder.setActualImageScaleType(ScalingUtils.ScaleType.FOCUS_CROP);
//缩放类型为focusCrop时,需要设定一个居中点
//(0f,0f)表示左上对齐显示,(1f,1f)表示右下对齐显示
PointF pf = new PointF(1f,1f);
builder.setActualImageFocusPoint(pf);
//进度条,占位图片消失,加载图片展现的时间间隔
builder.setFadeDuration(1000);
//加载失败之后显示的图片及图片缩放类型
builder.setFailureImage(R.drawable.imgbg, ScalingUtils.ScaleType.CENTER_INSIDE);
//设置占位图片及缩放类型
builder.setPlaceholderImage(R.drawable.imgbg, ScalingUtils.ScaleType.FIT_CENTER);
//加载进度条图片及缩放类型
builder.setProgressBarImage(R.drawable.progress_bar, ScalingUtils.ScaleType.CENTER_INSIDE);
//提示重新加载的图片及缩放类型
builder.setRetryImage(R.mipmap.ic_launcher, ScalingUtils.ScaleType.CENTER_CROP);
//设置背景图片
builder.setBackground(getResources().getDrawable(R.color.colorWhite));
//在图片上方覆盖一个图片资源
builder.setOverlay(getResources().getDrawable(R.drawable.overlay));
builder.setPressedStateOverlay(getResources().getDrawable(R.color.colorBlack));
RoundingParams rp = new RoundingParams();
//是否要将图片剪切成圆形
rp.setRoundAsCircle(false);
//设置哪个角需要变成圆角
rp.setCornersRadii(100f,0f,100f,0f);
//圆角部分填充色
rp.setOverlayColor(getResources().getColor(R.color.colorWhite));
//边框宽度
rp.setBorderWidth(20f);
//边框填充色
rp.setBorderColor(getResources().getColor(R.color.colorBlack));
builder.setRoundingParams(rp);
//得到DraweeHierarchy实例
GenericDraweeHierarchy hierachy = builder.build();
//在Drawee中设置DraweeHierarchy
sdv.setHierarchy(hierachy);
4、加载示例
public class MainActivity extends AppCompatActivity {
private SimpleDraweeView mSimpleDraweeView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.INTERNET, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 200);
}
mSimpleDraweeView = findViewById(R.id.mSimpleDraweeView);
String path = "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1089874897,1268118658&fm=26&gp=0.jpg";
loadPic(mSimpleDraweeView, path);
}
private void loadPic(SimpleDraweeView mSimpleDraweeView, String path) {
Uri uri = Uri.parse(path);
mSimpleDraweeView.setImageURI(uri);
}
}
三、拓展
1、图片上方覆盖多个图片资源
GenericDraweeHierarchyBuilder builder =new GenericDraweeHierarchyBuilder(getResources());
//多个图片资源
List<Drawable> overlaysList;
builder.setOverlays(overlaysList);
//进度条
builder.setProgressBarImage(new ProgressBarDrawable());
2、DraweeController
DraweeController主要是用于对图片进行更多的控制和定制,可以对加载事件进行监听,对加载之后的图片进行压缩和者修改,在加载失败之后重新加载图片和实现多图请求。
PipelineDraweeControllerBuilder sdcb = Fresco.newDraweeControllerBuilder();
//设置uri
sdcb.setUri(uri);
//加载失败之后,点击提示重新加载的图片资源重新加载
sdcb.setTapToRetryEnabled(true);
//在指定一个新的controller的时候,使用setOldController,这可节省不必要的内存分配。
sdcb.setOldController(sdv.getController());
DraweeController controller = sdcb.build();
sdv.setController(controller);
3、图片下载监听
ControllerListener listener = new BaseControllerListener<ImageInfo>(){
@Override
public void onSubmit(String id, Object callerContext) {
//提交请求之前调用的方法
Log.d(TAG, "onSubmit: " + id);
}
@Override
public void onFinalImageSet(String id, ImageInfo imageInfo, Animatable animatable) {
// 所有图片都加载成功时触发的方法
Log.d(TAG, "onFinalImageSet: " + id);
}
@Override
public void onIntermediateImageSet(String id, ImageInfo imageInfo) {
//当中间图片下载成功的时候触发,用于多图请求
}
@Override
public void onIntermediateImageFailed(String id, Throwable throwable) {
//当中间图片下载失败的时候触发,用于多图请求
}
@Override
public void onFailure(String id, Throwable throwable) {
// 加载图片失败时回调的方法
Log.d(TAG, "onFailure: " + id);
}
@Override
public void onRelease(String id) {
//释放图片资源时加载的方法
Log.d(TAG, "onRelease: " + id);
}
};
PipelineDraweeControllerBuilder sdcb = Fresco.newDraweeControllerBuilder();
sdcb.setControllerListener(listener);
4、ImageRequest
ImageRequest支持很多的功能,例如自动旋转图片,渐进式加载,图片缩放,后处理器,图片复用,最低请求级别等等。
ImageRequest request = ImageRequestBuilder
//设置URI
.newBuilderWithSource(uri)
//自动旋转
.setAutoRotateEnabled(true)
//最低级别请求
.setLowestPermittedRequestLevel(ImageRequest.RequestLevel.FULL_FETCH)
//图片缩放
.setResizeOptions(new ResizeOptions(width,height))
//渐进式加载
.setProgressiveRenderingEnabled(false)
.build();
PipelineDraweeControllerBuilder sdcb = Fresco.newDraweeControllerBuilder();
sdcb.setImageRequest(request);
DraweeController controller = sdcb.build();
sdv.setController(controller);
5、图片复用
假设一张图片具有多个URI,例如某张图片有各种比例的压缩图。我们在加载的时候,按顺序查找这些URI对应的图片是否存在,一旦找到第一个存在的,就进行展示。这也能有效避免我们去加载过大的图片。
ImageRequest request1 = ImageRequest.fromUri(uri1);
ImageRequest request2 = ImageRequest.fromUri(uri);
ImageRequest[] request = {request1,request2};
PipelineDraweeControllerBuilder sdcb = Fresco.newDraweeControllerBuilder();
sdcb.setFirstAvailableImageRequests(request);
DraweeController controller = sdcb.build();
sdv.setController(controller);
6、后处理器:PostProcessor
PostProcessor主要用于对加载完的图片进行处理,图片在进入后处理器(postprocessor)的图片是原图的一个完整拷贝,原来的图片不受修改的影响。在5.0以前的机器上,拷贝后的图片也在native内存中。
在开始一个图片显示时,即使是反复显示同一个图片,在每次进行显示时,都需要指定后处理器。对于同一个图片,每次显示可以使用不同的后处理器。
通常通过继承BaseProcessor来实现处理,通过重写Process方法来进行图片处理。BaseProcessor中提供了三个不同输入形参的process方法来给我们实现重写。
public class MyPostprocessor extends BasePostprocessor {
@Override
public String getName() {
return "redMeshPostprocessor";
}
//对图片进行即时后处理
//代码中在图片加上红点
@Override
public void process(Bitmap bitmap) {
for (int x = 0; x < bitmap.getWidth(); x+=4) {
for (int y = 0; y < bitmap.getHeight(); y+=4) {
bitmap.setPixel(x, y, Color.RED);
}
}
}
//对图片无法进行即时处理
//代码中对图片进行反转,目标图片的处理需要用到原始图片的信息
@Override
public void process(Bitmap destBitmap, Bitmap sourceBitmap) {
super.process(destBitmap, sourceBitmap);
for (int x = 0; x < destBitmap.getWidth(); x++) {
for (int y = 0; y < destBitmap.getHeight(); y++) {
destBitmap.setPixel(destBitmap.getWidth() - 1 - x, y, sourceBitmap.getPixel(x, y));
}
}
}
//只用于处理后图片和源图片大小不一样的情况
//代码中将图片长宽都压缩为原来的1/4
@Override
public CloseableReference<Bitmap> process(
Bitmap sourceBitmap,
PlatformBitmapFactory bitmapFactory) {
int scale = 4;
CloseableReference<Bitmap> bitmapRef = bitmapFactory.createBitmap(
sourceBitmap.getWidth() / scale,
sourceBitmap.getHeight() / scale);
try {
Bitmap destBitmap = bitmapRef.get();
for (int x = 0; x < destBitmap.getWidth(); x++) {
for (int y = 0; y < destBitmap.getHeight(); y++) {
destBitmap.setPixel(x, y, sourceBitmap.getPixel(scale*x, scale*y));
}
}
return CloseableReference.cloneOrNull(bitmapRef);
} finally {
CloseableReference.closeSafely(bitmapRef);
}
}
}
//后处理器
Postprocessor processor = new MyPostprocessor();
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri).setPostprocessor(processor).build();
PipelineDraweeControllerBuilder sdcb = Fresco.newDraweeControllerBuilder();
sdcb.setImageRequest(request);
DraweeController controller = sdcb.build();
sdv.setController(controller);
四、性能分析
这篇文件写的很详细,记录一下:https://blog.csdn.net/github_33304260/article/details/70213300
网友评论