点击查看原文

  Fresco是Facebook推出的一款用于Android应用中展示图片的强大图片库。它具有强大的内存管理、渐进式呈现图片、支持加载Gif图和WebP格式等特点。

  相比于其他图片框架要庞大的多,但是对于图片的处理也要比其他框架支持的多。

  Fresco官方中文介绍文档:https://www.fresco-cn.org/

  Fresco GitHub 地址:https://github.com/facebook/fresco

Fresco使用

  1.添加依赖

compile 'com.facebook.fresco:fresco:1.10.0'

  其他相关依赖

compile 'com.facebook.fresco:animated-gif:1.5.0'//加载gif动图需添加此库
compile 'com.facebook.fresco:animated-webp:1.5.0'//加载webp动图需添加此库
compile 'com.facebook.fresco:webpsupport:1.5.0'//支持webp需添加此库
compile 'com.facebook.fresco:imagepipeline-okhttp3:1.5.0'//网络实现层使用okhttp3需添加此库
compile 'jp.wasabeef:fresco-processors:2.1.0@aar'//用于提供fresco的各种图片变换

  2.图片加载布局控件

  必须设置layout_width、layout_height两个属性,否则无法展示。并且注意SimpleDraweeView不支持wrap_content属性。可以参考官方文档:wrap_content的限制 。你必须指定尺寸或者用match_parent来布局。

复制代码
<com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/sdv_fresco"
        android:layout_width="130dp"
        android:layout_gravity="center"
        android:layout_height="130dp"
        fresco:placeholderImage="@drawable/atguigu_logo" />
复制代码

  3.常用属性

  3.1 带进度条的图片

复制代码
  // 设置样式
    GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(getResources());
    GenericDraweeHierarchy hierarchy = builder.setProgressBarImage(new ProgressBarDrawable()).build();
    sdvFresco.setHierarchy(hierarchy);
    // 加载图片的地址
    Uri uri = Uri.parse("http://");
    // 加载图片
    sdvFresco.setImageURI(uri);
复制代码

  3.2 图片的不同裁剪

    CENTER

复制代码
  GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(getResources());

</span><span style="color: #008000;">//</span><span style="color: #008000;">居中,无缩放</span>
GenericDraweeHierarchy hierarchy =<span style="color: #000000;"> builder.setActualImageScaleType(ScalingUtils.ScaleType.CENTER).build();</span><span style="color: #008000;">//</span><span style="color: #008000;"> 设置样式</span>

sdvFresco.setHierarchy(hierarchy);
// 加载图片的地址
Uri uri = Uri.parse(http://);
// 加载图片
sdvFresco.setImageURI(uri);

复制代码

  CENTER_CROP

//保持宽高比缩小或放大,使得两边都大于或等于显示边界。居中显示
    GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_CROP).build();

  FOCUS_CROP

// 同centerCrop, 但居中点不是中点,而是指定的某个点,这里我设置为图片的左上角那点
    PointF point = new PointF(0,0);
    GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.FOCUS_CROP)

  CENTER_INSIDE

//使两边都在显示边界内,居中显示。如果图尺寸大于显示边界,则保持长宽比缩小图片
    GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_INSIDE).build();

  FIT_CENTER

//保持宽高比,缩小或者放大,使得图片完全显示在显示边界内。居中显示
    GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.FIT_CENTER).build();

  FIT_START

//保持宽高比,缩小或者放大,使得图片完全显示在显示边界内,不居中,和显示边界左上对齐
    GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.FIT_START).build();

  FIT_END

//保持宽高比,缩小或者放大,使得图片完全显示在显示边界内,不居中,和显示边界右下对齐
    GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.FIT_END).build();

  FIT_XY

//不保持宽高比,填充满显示边界
    GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.FIT_XY).build();

  title mode

//如要使用title mode显示, 需要设置为none
    GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(null).build();

  3.3 圆形和圆角图片  

复制代码
  //圆形图片
    parames = RoundingParams.asCircle();
    GenericDraweeHierarchy hierarchy = builder.setRoundingParams(parames).build();


</span><span style="color: #008000;">//</span><span style="color: #008000;">圆角图片</span>
parames =<span style="color: #000000;"> RoundingParams.fromCornersRadius(50f);
</span><span style="color: #008000;">//</span><span style="color: #008000;">parames.setOverlayColor(getResources().getColor(android.R.color.holo_red_light));</span><span style="color: #008000;">//</span><span style="color: #008000;">覆盖层
</span><span style="color: #008000;">//</span><span style="color: #008000;">parames.setBorder(getResources().getColor(android.R.color.holo_blue_light), 5);</span><span style="color: #008000;">//</span><span style="color: #008000;">边框</span>
GenericDraweeHierarchy hierarchy = builder.setRoundingParams(parames).build();</pre>
复制代码

  3.4 渐进式展示图片

复制代码
  // 加载质量配置
    ProgressiveJpegConfig jpegConfig = new ProgressiveJpegConfig() {
        @Override
        public int getNextScanNumberToDecode(int scanNumber) {
            return scanNumber + 2;
        }

    @Override
    </span><span style="color: #0000ff;">public</span> QualityInfo getQualityInfo(<span style="color: #0000ff;">int</span><span style="color: #000000;"> scanNumber) {
        boolean isGoodEnough </span>= (scanNumber &gt;= <span style="color: #800080;">5</span><span style="color: #000000;">);

        </span><span style="color: #0000ff;">return</span> ImmutableQualityInfo.of(scanNumber, isGoodEnough, <span style="color: #0000ff;">false</span><span style="color: #000000;">);
    }
};

ImagePipelineConfig.newBuilder(</span><span style="color: #0000ff;">this</span><span style="color: #000000;">).setProgressiveJpegConfig(jpegConfig).build();
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 获取图片URL</span>
Uri uri = Uri.parse(<span style="color: #800000;">"</span><span style="color: #800000;">http://</span><span style="color: #800000;">"</span><span style="color: #000000;">);
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 获取图片请求</span>
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri).setProgressiveRenderingEnabled(<span style="color: #0000ff;">true</span><span style="color: #000000;">).build();
DraweeController draweeController </span>=<span style="color: #000000;"> Fresco.newDraweeControllerBuilder()
        .setImageRequest(request)
        .setTapToRetryEnabled(</span><span style="color: #0000ff;">true</span><span style="color: #000000;">)
        .setOldController(sdvFresco.getController())</span><span style="color: #008000;">//</span><span style="color: #008000;">使用oldController可以节省不必要的内存分配</span>

.build();

</span><span style="color: #008000;">//</span><span style="color: #008000;"> 设置加载的控制</span>
sdvFresco.setController(draweeController);</pre>
复制代码

  3.5 GIF动画图片

复制代码
  Uri uri = Uri.parse("http://");
    DraweeController controller = Fresco.newDraweeControllerBuilder()
            .setUri(uri)
            .setAutoPlayAnimations(true) //是否自动播放
            .setOldController(sdvFresco.getController())
            .build();

sdvFresco.setController(controller);

</span><span style="color: #008000;">//</span><span style="color: #008000;"> 动画开始</span>
Animatable animatable =<span style="color: #000000;"> sdvFresco.getController().getAnimatable();
</span><span style="color: #0000ff;">if</span>(animatable != <span style="color: #0000ff;">null</span> &amp;&amp; !<span style="color: #000000;">animatable.isRunning()) {
    animatable.start();
}

</span><span style="color: #008000;">//</span><span style="color: #008000;">动画停止</span>
 Animatable animatable =<span style="color: #000000;"> sdvFresco.getController().getAnimatable();
</span><span style="color: #0000ff;">if</span>(animatable != <span style="color: #0000ff;">null</span> &amp;&amp;<span style="color: #000000;"> animatable.isRunning()) {
    animatable.stop();
}</span></pre>
复制代码

  3.6 多图请求及图片复用

    先显示低分辨率的图,然后是高分辨率的图

复制代码
  // 图片地址
    Uri lowUri = Uri.parse("http://");
    Uri highUri = Uri.parse("http://");
    // 控制加载图片
    DraweeController controller = Fresco.newDraweeControllerBuilder()
            .setLowResImageRequest(ImageRequest.fromUri(lowUri))
            .setImageRequest(ImageRequest.fromUri(highUri))
            .build();
    // 加载图片
    sdvFresco.setController(controller);

本地缩略图预览
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 图片地址</span>
Uri uri = Uri.fromFile(<span style="color: #0000ff;">new</span> File(Environment.getExternalStorageDirectory() +<span style="color: #800000;">"</span><span style="color: #800000;">/meinv1.jpg</span><span style="color: #800000;">"</span><span style="color: #000000;">));
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 加载图片的请求</span>
ImageRequest request =<span style="color: #000000;"> ImageRequestBuilder.newBuilderWithSource(uri)
        .setLocalThumbnailPreviewsEnabled(</span><span style="color: #0000ff;">true</span><span style="color: #000000;">)
        .build();
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 控制图片的加载</span>
DraweeController controller =<span style="color: #000000;"> Fresco.newDraweeControllerBuilder()
        .setImageRequest(request)
        .build();
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 加载图片</span>

sdvFresco.setController(controller);

本地图片复用
</span><span style="color: #008000;">//</span><span style="color: #008000;">本地图片的复用
</span><span style="color: #008000;">//</span><span style="color: #008000;">在请求之前,还会去内存中请求一次图片,没有才会先去本地,最后去网络uri
</span><span style="color: #008000;">//</span><span style="color: #008000;">本地准备复用图片的uri  如果本地这个图片不存在,会自动去加载下一个uri
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 请求加载图片</span>
Uri uri1 = Uri.fromFile(<span style="color: #0000ff;">new</span> File(Environment.getExternalStorageDirectory()+<span style="color: #800000;">"</span><span style="color: #800000;">/meinv.jpg</span><span style="color: #800000;">"</span><span style="color: #000000;">));
</span><span style="color: #008000;">//</span><span style="color: #008000;">图片的网络uri</span>
Uri uri2 = Uri.parse(<span style="color: #800000;">"</span><span style="color: #800000;">http://</span><span style="color: #800000;">"</span><span style="color: #000000;">);
ImageRequest request1 </span>=<span style="color: #000000;"> ImageRequest.fromUri(uri1);
ImageRequest request2 </span>=<span style="color: #000000;"> ImageRequest.fromUri(uri2);
ImageRequest[] requests </span>=<span style="color: #000000;"> {request1, request2};
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 控制加载图片</span>
DraweeController controller =<span style="color: #000000;"> Fresco.newDraweeControllerBuilder()
        .setFirstAvailableImageRequests(requests)
        .setOldController(sdvFresco.getController())
        .build();
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 加载图片</span>
sdvFresco.setController(controller);</pre>
复制代码

  3.7 图片加载监听

复制代码
    // 图片加载的控制
     //添加监听事件 .setControllerListener(controllerListener)
    SimpleDraweeView sdvFrescoListener;

DraweeController controller </span>=<span style="color: #000000;"> Fresco.newDraweeControllerBuilder()
        .setOldController(sdvFrescoListener.getController())
        .setImageRequest(request)
        .setControllerListener(controllerListener)
        .build();</span></pre>
复制代码
复制代码
private ControllerListener controllerListener = new BaseControllerListener<ImageInfo>(){
        // 加载图片完毕
        @Override
        public void onFinalImageSet(String id, ImageInfo imageInfo, Animatable animatable) {
            super.onFinalImageSet(id, imageInfo, animatable);

    </span><span style="color: #0000ff;">if</span> (imageInfo == <span style="color: #0000ff;">null</span><span style="color: #000000;">) {
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;">;
    }

    </span><span style="color: #008000;">//</span><span style="color: #008000;"> 获取图片的质量</span>
    QualityInfo qualityInfo =<span style="color: #000000;"> imageInfo.getQualityInfo();

    </span><span style="color: #008000;">//</span><span style="color: #008000;">页面文本打印setText</span>
    tvFrescoListener.setText(<span style="color: #800000;">"</span><span style="color: #800000;">Final image received! </span><span style="color: #800000;">"</span> +
            <span style="color: #800000;">"</span><span style="color: #800000;">\nSize: </span><span style="color: #800000;">"</span> +<span style="color: #000000;"> imageInfo.getWidth()
            </span>+ <span style="color: #800000;">"</span><span style="color: #800000;">x</span><span style="color: #800000;">"</span> +<span style="color: #000000;"> imageInfo.getHeight()
            </span>+ <span style="color: #800000;">"</span><span style="color: #800000;">\nQuality level: </span><span style="color: #800000;">"</span> +<span style="color: #000000;"> qualityInfo.getQuality()
            </span>+ <span style="color: #800000;">"</span><span style="color: #800000;">\ngood enough: </span><span style="color: #800000;">"</span> +<span style="color: #000000;"> qualityInfo.isOfGoodEnoughQuality()
            </span>+ <span style="color: #800000;">"</span><span style="color: #800000;">\nfull quality: </span><span style="color: #800000;">"</span> +<span style="color: #000000;"> qualityInfo.isOfFullQuality());
}

</span><span style="color: #008000;">//</span><span style="color: #008000;"> 渐进式加载图片回调</span>

@Override
public void onIntermediateImageSet(String id, ImageInfo imageInfo) {
super.onIntermediateImageSet(id, imageInfo);

    tvFrescoListener2.setText(</span><span style="color: #800000;">"</span><span style="color: #800000;">IntermediateImageSet image receiced</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}

</span><span style="color: #008000;">//</span><span style="color: #008000;"> 加载图片失败</span>

@Override
public void onFailure(String id, Throwable throwable) {
super.onFailure(id, throwable);

        tvFrescoListener.setText(</span><span style="color: #800000;">"</span><span style="color: #800000;">Error loading</span><span style="color: #800000;">"</span> +<span style="color: #000000;"> id);
    }
}</span></pre>
复制代码

  3.8 图片修改和旋转

    修内存中改图片大小 setResizeOptions 

复制代码
   // 图片地址
    Uri uri = Uri.parse("http://");
    // 图片的请求
    ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
            .setResizeOptions(new ResizeOptions(50,50))
            .build();
    // 控制图片的加载
    PipelineDraweeController controller = (PipelineDraweeController) Fresco.newDraweeControllerBuilder()
            .setOldController(sdvFresco.getController())
            .setImageRequest(request)
            .build();
    // 加载图片
    sdvFresco.setController(controller);
复制代码

    旋转图片 setAutoRotateEnabled

复制代码
  Uri uri = Uri.parse("http://");
    ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
            .setAutoRotateEnabled(true)
            .build();
    // 控制图片的加载
    DraweeController controller = Fresco.newDraweeControllerBuilder()
            .setOldController(sdvFresco.getController())
            .setImageRequest(request)
            .build();
    // 加载图片
    sdvFresco.setController(controller);
复制代码

  3.9 修改图片(显示过程同上,主要更改了ImageRequest设置) setPostprocessor

复制代码
    // 修改图片
    Postprocessor postProcessor = new BasePostprocessor() {
        @Override
        public String getName() {
            return "postProcessor";
        }
        @Override
        public void process(Bitmap bitmap) {
            for (int x = 0; x < bitmap.getWidth(); x += 2) {
                for (int y = 0; y < bitmap.getHeight(); y += 2) {
                    bitmap.setPixel(x, y, Color.RED);
                }
            }
        }
    };

</span><span style="color: #008000;">//</span><span style="color: #008000;"> 创建图片请求</span>
ImageRequest request =<span style="color: #000000;"> ImageRequestBuilder.newBuilderWithSource(uri)
        .setPostprocessor(postProcessor)
        .build();</span></pre>
复制代码

   3.10 动态展示图片(添加SimpleDraweeView到LinearLayout中)

复制代码
  SimpleDraweeView simpleDraweeView = new SimpleDraweeView(this);
    // 设置宽高比
    simpleDraweeView.setAspectRatio(3.0f);

</span><span style="color: #008000;">//</span><span style="color: #008000;"> 图片的地址</span>
Uri uri = Uri.parse(<span style="color: #800000;">"</span><span style="color: #800000;">http://</span><span style="color: #800000;">"</span><span style="color: #000000;">);
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 图片的请求</span>
ImageRequest request =<span style="color: #000000;"> ImageRequestBuilder.newBuilderWithSource(uri)
        .build();
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 加载图片的控制</span>
PipelineDraweeController controller =<span style="color: #000000;"> (PipelineDraweeController) Fresco.newDraweeControllerBuilder()
        .setOldController(simpleDraweeView.getController())
        .setImageRequest(request)
        .build();

</span><span style="color: #008000;">//</span><span style="color: #008000;"> 加载图片</span>

simpleDraweeView.setController(controller);
// 添加View到线性布局中
linearLayout.addView(simpleDraweeView);

复制代码