美文网首页
Fressco图片加载框架

Fressco图片加载框架

作者: 放羊娃华振 | 来源:发表于2021-01-01 10:51 被阅读0次

一、概述

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

相关文章

网友评论

      本文标题:Fressco图片加载框架

      本文链接:https://www.haomeiwen.com/subject/sjtapctx.html