Android 图片加载框架之Fresco

    一、简介

        Fresco是Facebook推出的一款用于Android应用中展示图片的强大图片库,可以从网络、本地存储和本地资源中加载图片。相对于ImageLoader,拥有更快的图片下载速度以及可以加载和显示gif图等诸多优势,是个很好的图片框架。
    

    二、特点

        1)内存管理

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


        2)渐进式呈现图片

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


        3)支持加载Gif图,支持WebP格式。
        4)图像的呈现

            (1)自定义居中焦点(对人脸等图片显示非常有帮助)。
            (2)圆角图,当然圆圈也行。
            (3)下载失败之后,点击重新下载。
            (4)自定义占位图,自定义overlay, 或者进度条。
            (5)指定用户按压时的overlay。


        5)图像的加载

            (1)为同一个图片指定不同的远程路径,或者使用已经存在本地缓存中的图片。
            (2)先显示一个低解析度的图片,等高清图下载完之后再显示高清图。
            (3)加载完成回调通知。
            (4)对于本地图,如有EXIF缩略图,在大图加载完成之前,可先显示缩略图。
            (5)缩放或者旋转图片。
            (6)处理已下载的图片。


   三、下载地址

        https://github.com/facebook/fresco
        官方使用网址: http://fresco-cn.org/docs/index.html


   四、支持的URI

        1、远程图片
            http://, https://
        2、本地文件
            file://
        3、Content provider
            content://
        4、asset目录下的资源
            asset://
        5、res目录下的资源    
            res://
        6、Uri中指定图片数据
            data:mime/type;base64,

res示例:

Uri uri = Uri.parse("res://包名(实际可以是任何字符串甚至留空)/" + R.drawable.ic_launcher);


    五、常用API

        1、// 不支持wrap_content, 如果要设置宽高比, 需要在Java代码中指定setAspectRatio(float ratio);

android:layout_width="20dp"

        2、// 不支持wrap_content 

android:layout_height="20dp" 

        3、 // 下载成功之前显示的图片

fresco:placeholderImage="@color/wait_color"

        4、 // 设置图片缩放. 通常使用focusCrop,该属性值会通过算法把人头像放在中间

fresco:placeholderImageScaleType="fitCenter"

        5、// 加载失败的时候显示的图片

fresco:failureImage="@drawable/error"

         6、// 设置图片缩放

fresco:failureImageScaleType=“centerInside"

        7、// 加载失败,提示用户点击重新加载的图片(会覆盖failureImage的图片)

fresco:retryImage="@drawable/retrying"

        8、// 设置圆形方式显示图片

fresco:roundAsCircle="true"

        9、// 圆角设置

    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"

 

    六、使用步骤

        (1)添加依赖

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

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

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

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

  // 其他依赖
  implementation 'com.facebook.fresco:fresco:1.13.0'
}

        (2)在application中初始化Fresco

Fresco.initialize(this);

        (3)配置网络权限         

  <uses-permission android:name="android.permission.INTERNET"/>

        (4)在xml布局文件中,加入命名空间

<!-- 其他元素-->
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fresco="http://schemas.android.com/apk/res-auto"
    android:layout_height="match_parent"
    android:layout_width="match_parent">

        (5)在xml中引入SimpleDraweeView

<com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/my_image_view"
    android:layout_width="130dp"
    android:layout_height="130dp"
    fresco:placeholderImage="@drawable/my_drawable"
  />

        (6)在Java代码中开始加载图片

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);

        注意:
            如果项目中使用了OkHttp需要进行替换
            1、使用了OkHttp2要替换成下面的:                   

 compile "com.facebook.fresco:imagepipeline-okhttp:0.12.0+"

             2、使用了OkHttp3要替换成下面的:                    

compile "com.facebook.fresco:imagepipeline-okhttp3:0.12.0+"


    七、例子

        1)带进度条的图片
            (1)布局

    <com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/my_image_view"
        android:layout_width="130dp"
        android:layout_height="130dp"
        fresco:placeholderImage="@drawable/atguigu_logo"
        />

            (2)代码

private SimpleDraweeView simpleDraweeView;
       simpleDraweeView = (SimpleDraweeView)findViewById(R.id.my_image_view);
       //设置样式
        GenericDraweeHierarchyBuilder builder  = new GenericDraweeHierarchyBuilder(getResources());
        GenericDraweeHierarchy hierarchy = builder.setProgressBarImage(new ProgressBarDrawable()).build();
        simpleDraweeView.setHierarchy(hierarchy);
        //加载图片的地址
        Uri uri = Uri.parse("http://img4.duitang.com/uploads/item/201211/24/20121124175330_ruKEK.jpeg");
        //加载图片
        simpleDraweeView.setImageURI(uri);


        2)图片的不同裁剪

            (1)布局

    <com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/sdv_fresco_crop"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_marginTop="48dp"
        android:background="@android:color/black"
        fresco:placeholderImage="@drawable/atguigu_logo" />

            (2)代码设置

                CENTER:居中,无缩放

        text.setText("居中,无缩放");
        //设置样式
        GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.CENTER).build();
        sdvFrescoCrop.setHierarchy(hierarchy);
        //加载图片
        Uri uri = Uri.parse("http://img4q.duitang.com/uploads/item/201305/20/20130520115416_VrUUR.jpeg");
        sdvFrescoCrop.setImageURI(uri);

                CENTER_CROP:保持宽高比缩小或放大,使得两边都大于或等于显示边界。居中显示

        text.setText("保持宽高比缩小或放大,使得两边都大于或等于显示边界。居中显示");
        //设置样式
        GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_CROP).build();
        sdvFrescoCrop.setHierarchy(hierarchy);
        //加载图片
        Uri uri = Uri.parse("http://img4q.duitang.com/uploads/item/201305/20/20130520115416_VrUUR.jpeg");
        sdvFrescoCrop.setImageURI(uri);

                FOCUS_CROP:同centerCrop, 但居中点不是中点,而是指定的某个点,这里我设置为图片的左上角那点

        text.setText("同centerCrop, 但居中点不是中点,而是指定的某个点,这里我设置为图片的左上角那点");
        //设置样式
        PointF point = new PointF(0,0);
        GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.FOCUS_CROP).setActualImageFocusPoint(point).build();
        sdvFrescoCrop.setHierarchy(hierarchy);
        //加载图片
        Uri uri = Uri.parse("http://img4q.duitang.com/uploads/item/201305/20/20130520115416_VrUUR.jpeg");
        sdvFrescoCrop.setImageURI(uri);

                CENTER_INSIDE:使两边都在显示边界内,居中显示。如果图尺寸大于显示边界,则保持长宽比缩小图片

        text.setText("使两边都在显示边界内,居中显示。如果图尺寸大于显示边界,则保持长宽比缩小图片");
        //设置样式
        GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_INSIDE).build();
        sdvFrescoCrop.setHierarchy(hierarchy);
        //加载图片
        Uri uri = Uri.parse("http://img4q.duitang.com/uploads/item/201305/20/20130520115416_VrUUR.jpeg");
        sdvFrescoCrop.setImageURI(uri);

                FIT_CENTER:保持宽高比,缩小或者放大,使得图片完全显示在显示边界内。居中显示

        text.setText("保持宽高比,缩小或者放大,使得图片完全显示在显示边界内。居中显示");
        //设置样式
        GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.FIT_END).build();
        sdvFrescoCrop.setHierarchy(hierarchy);
        //加载图片
        Uri uri = Uri.parse("http://img4q.duitang.com/uploads/item/201305/20/20130520115416_VrUUR.jpeg");
        sdvFrescoCrop.setImageURI(uri);

                FIT_START:保持宽高比,缩小或者放大,使得图片完全显示在显示边界内,不居中,和显示边界左上对齐

        text.setText("保持宽高比,缩小或者放大,使得图片完全显示在显示边界内,不居中,和显示边界左上对齐");
        //设置样式
        GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.FIT_START).build();
        sdvFrescoCrop.setHierarchy(hierarchy);
        //加载图片
        Uri uri = Uri.parse("http://img4q.duitang.com/uploads/item/201305/20/20130520115416_VrUUR.jpeg");
        sdvFrescoCrop.setImageURI(uri);

              FIT_END:保持宽高比,缩小或者放大,使得图片完全显示在显示边界内,不居中,和显示边界右下对齐

        text.setText("保持宽高比,缩小或者放大,使得图片完全显示在显示边界内,不居中,和显示边界右下对齐");
        //设置样式
        GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.FIT_END).build();
        sdvFrescoCrop.setHierarchy(hierarchy);
        //加载图片
        Uri uri = Uri.parse("http://img4q.duitang.com/uploads/item/201305/20/20130520115416_VrUUR.jpeg");
        sdvFrescoCrop.setImageURI(uri);

                FIT_XY:不保持宽高比,填充满显示边界

        text.setText("不保持宽高比,填充满显示边界");
        //设置样式
        GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.FIT_XY).build();
        sdvFrescoCrop.setHierarchy(hierarchy);
        //加载图片
        Uri uri = Uri.parse("http://img4q.duitang.com/uploads/item/201305/20/20130520115416_VrUUR.jpeg");
        sdvFrescoCrop.setImageURI(uri);

                none:如要使用title mode显示, 需要设置为none

        text.setText("如要使用title mode显示, 需要设置为none");
        //设置样式
        GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(null).build();
        sdvFrescoCrop.setHierarchy(hierarchy);
        //加载图片
        Uri uri = Uri.parse("http://img4q.duitang.com/uploads/item/201305/20/20130520115416_VrUUR.jpeg");
        sdvFrescoCrop.setImageURI(uri);

            
        3)圆形和圆角图片

            (1)布局

    <com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/sdv_fresco_circleandcorner"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_gravity="center"
        fresco:placeholderImage="@drawable/atguigu_logo" />

            (2)设置圆形图片

                //设置圆形图片
                RoundingParams params = RoundingParams.asCircle();
                GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(getResources());
                GenericDraweeHierarchy hierarchy = builder.setRoundingParams(params).build();
                sdvFrescoCircleandcorner.setHierarchy(hierarchy);

                Uri uri = Uri.parse("http://img4q.duitang.com/uploads/item/201304/27/20130427043538_wAfHC.jpeg");
                sdvFrescoCircleandcorner.setImageURI(uri);

             (3)设置圆角图片

                RoundingParams params = RoundingParams.fromCornersRadius(50f);
                //设置圆角的颜色
                params.setOverlayColor(getResources().getColor(android.R.color.holo_red_light));
                //设置边框的颜色
                params.setBorder(getResources().getColor(android.R.color.holo_blue_light),5);
                GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(getResources());
                GenericDraweeHierarchy hierarchy = builder.setRoundingParams(params).build();
                sdvFrescoCircleandcorner.setHierarchy(hierarchy);

                Uri uri = Uri.parse("http://img4q.duitang.com/uploads/item/201304/27/20130427043538_wAfHC.jpeg");
                sdvFrescoCircleandcorner.setImageURI(uri);

        4)渐进式展示图片
            (1)布局

    <com.facebook.drawee.view.SimpleDraweeView
        android:layout_gravity="center"
        android:id="@+id/sdv_fresco_jpeg"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_marginTop="48dp"
        fresco:placeholderImage="@drawable/atguigu_logo" />

            (2)代码

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

            @Override
            public QualityInfo getQualityInfo(int scanNumber) {
                boolean isGoodEnough = (scanNumber >= 5);
                return ImmutableQualityInfo.of(scanNumber,isGoodEnough,false);
            }
        };
        ImagePipelineConfig.newBuilder(this).setProgressiveJpegConfig(jpegConfig).build();
        //获取图片URL
        Uri uri = Uri.parse("http://cdn.duitang.com/uploads/item/201303/12/20130312021353_45Qix.jpeg");
        //获取图片请求
        ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri).setProgressiveRenderingEnabled(true).build();

        DraweeController draweeController = Fresco.newDraweeControllerBuilder()
                .setImageRequest(request)
                .setTapToRetryEnabled(true)
                .setOldController(sdvFrescoJpeg.getController())
                .build();
        //设置加载的控制
        sdvFrescoJpeg.setController(draweeController);

        5)Gif动画图片
            (1)布局

    <com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/sdv_fresco_gif"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_marginTop="48dp"
        android:layout_gravity="center"
        fresco:placeholderImage="@drawable/atguigu_logo" />

            (2)添加依赖            

compile 'com.facebook.fresco:animated-gif:1.13.0'

注意:添加的依赖版本要和

implementation 'com.facebook.fresco:fresco:1.13.0'

版本一样,不然动画不会动。


            (3)代码
                a)请求图片

                Uri uri = Uri.parse("http://wx2.sinaimg.cn/large/005xLWargy1fj8wh3yw1wg30a006on2e.gif");
                DraweeController controller = Fresco.newDraweeControllerBuilder()
                        .setUri(uri)
                        .setAutoPlayAnimations(true) //动画默认开始状态
                        .setOldController(sdvFrescoGif.getController())
                        .build();
                sdvFrescoGif.setController(controller);

                b)开始动画

                animatable = sdvFrescoGif.getController().getAnimatable();
                if(animatable != null && !animatable.isRunning()){
                    animatable.start();
                }

                c)停止动画

                Animatable animatable = sdvFrescoGif.getController().getAnimatable();
                if(animatable != null && animatable.isRunning()){
                    animatable.stop();
                }


        6)多图请求及图片复用
            (1)布局

    <com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/sdv_fresco_multi"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_gravity="center"
        android:layout_marginTop="48dp"
        fresco:placeholderImage="@drawable/atguigu_logo" />

            (2)代码
                a)先显示低分辨率的图,然后是高分辨率的图

                //图片地址
                Uri lowUri = Uri.parse("http://img1.gamedog.cn/2012/03/11/19-120311133617-50.jpg");
                Uri hightUri = Uri.parse("http://img5.duitang.com/uploads/item/201312/03/20131203153823_Y4y8F.jpeg");
                //控制加载图片
                DraweeController controller = Fresco.newDraweeControllerBuilder()
                        .setLowResImageRequest(ImageRequest.fromUri(lowUri))
                        .setImageRequest(ImageRequest.fromUri(hightUri))
                        .build();
                //加载图片
                sdvFrescoMulti.setController(controller);

                b)本地缩略图预览

                //图片地址
                Uri uri = Uri.fromFile(new File(Environment.getExternalStorageDirectory()+"/c.png"));
                //加载图片的请求
                ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                        .setLocalThumbnailPreviewsEnabled(true)//缩略图
                        .build();
                //控制图片的加载
                DraweeController controller1 = Fresco.newDraweeControllerBuilder()
                        .setImageRequest(request)
                        .build();
                //加载图片
                sdvFrescoMulti.setController(controller1);

                c)本地图片复用

                   在请求之前,还会去内存中请求一次图片,没有才会先去本地,最后才去网络uri

                   本地准备复用图片的uri,如果本地这个图片不存在,会自动去加载下一个uri

                //请求加载图片
                Uri uri1 = Uri.fromFile(new File(Environment.getExternalStorageDirectory()+"/dd.jpg"));
                //图片的网络uri
                Uri uri2 = Uri.parse("http://img5.duitang.com/uploads/item/201312/03/20131203153823_Y4y8F.jpeg");
                ImageRequest request1 = ImageRequest.fromUri(uri1);
                ImageRequest request2 = ImageRequest.fromUri(uri2);
                ImageRequest[] requests = {request1,request2};

                //控制加载图片
                DraweeController controller2 = Fresco.newDraweeControllerBuilder()
                        .setFirstAvailableImageRequests(requests)
                        .setOldController(sdvFrescoMulti.getController())
                        .build();

                //加载图片
                sdvFrescoMulti.setController(controller2);

        7)图片加载监听

             对所有的图片加载,onFinalImageSet 或者 onFailure 都会被触发。前者在成功时,后者在失败时。

             如果允许呈现渐进式JPEG,同时图片也是渐进式图片,onIntermediateImageSet会在每个扫描被解码后回调。

            (1)布局

    <com.facebook.drawee.view.SimpleDraweeView
        android:layout_gravity="center"
        android:id="@+id/sdv_fresco_listener"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_marginTop="48dp"
        fresco:placeholderImage="@drawable/atguigu_logo" />

    <Button
        android:id="@+id/bt_fresco_listener"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="48dp"
        android:text="开始加载图片" />

    <TextView
        android:id="@+id/tv_fresco_listener"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="@android:color/black"
        android:textSize="14sp" />

    <TextView
        android:id="@+id/tv_fresco_listener2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="@android:color/black"
        android:textSize="14sp" />

            (2)代码

 加载图片监听:

        ControllerListener  listener = new BaseControllerListener<ImageInfo>(){
            //加载图片完毕
            @Override
            public void onFinalImageSet(String id, @Nullable ImageInfo imageInfo, @Nullable Animatable animatable) {
                super.onFinalImageSet(id, imageInfo, animatable);
                super.onIntermediateImageSet(id, imageInfo);

                tvFrescoListener2.setText("IntermediateImageSet image receiced");

            }

            //渐进式加载图片回调
            @Override
            public void onIntermediateImageSet(String id, @Nullable ImageInfo imageInfo) {
                super.onIntermediateImageSet(id, imageInfo);
                if (imageInfo == null) {
                    return;
                }

                QualityInfo qualityInfo = imageInfo.getQualityInfo();

                tvFrescoListener.setText("Final image received! " +
                        "\nSize: " + imageInfo.getWidth()
                        + "x" + imageInfo.getHeight()
                        + "\nQuality level: " + qualityInfo.getQuality()
                        + "\ngood enough: " + qualityInfo.isOfGoodEnoughQuality()
                        + "\nfull quality: " + qualityInfo.isOfFullQuality());

            }

            //加载图片失败
            @Override
            public void onFailure(String id, Throwable throwable) {
                super.onFailure(id, throwable);
                tvFrescoListener.setText("Error loading" + id);
            }
        };

加载图片: 

        //图片地址
        Uri uri = Uri.parse("http://cdn.duitang.com/uploads/item/201303/12/20130312021353_45Qix.jpeg");
        //图片请求
        ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                .setProgressiveRenderingEnabled(true)
                .build();
        //图片加载控制
        DraweeController controller = Fresco.newDraweeControllerBuilder()
                .setOldController(sdvFrescoListener.getController())
                .setImageRequest(request)
                .setControllerListener(listener)
                .build();
        //加载图片
        sdvFrescoListener.setController(controller);

图片质量的配置:

        ProgressiveJpegConfig jpegConfig = new ProgressiveJpegConfig() {
            @Override
            public int getNextScanNumberToDecode(int scanNumber) {
                return scanNumber + 2;
            }

            @Override
            public QualityInfo getQualityInfo(int scanNumber) {
                boolean isGoodEnough = (scanNumber >= 5);

                return ImmutableQualityInfo.of(scanNumber, isGoodEnough, false);
            }
        };


        8)图片缩放和旋转
            (1)布局
            (2)代码
                a)缩放

          ---->        

                //图片地址
                Uri uri = Uri.parse("https://pub-static.haozhaopian.net/static/web/site/features/cn/crop/images/crop_20a7dc7fbd29d679b456fa0f77bd9525d.jpg");
                //图片的请求
                ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                        .setResizeOptions(new ResizeOptions(50,50))
                        .build();
                //图片加载的控制
                PipelineDraweeController controller = (PipelineDraweeController) Fresco.newDraweeControllerBuilder()
                        .setImageRequest(request)
                        .setOldController(sdvFrescoResize.getController())
                        .build();
                //加载图片
                sdvFrescoResize.setController(controller);

                b)自动旋转

        如果看到的图片是侧着的,用户会非常难受。许多设备会在 JPEG 文件的 metadata 中记录下照片的方向。如果你想图片呈现的方向和设备屏幕的方向一致。

                //图片地址
                Uri uri1 = Uri.parse("https://pub-static.haozhaopian.net/static/web/site/features/cn/crop/images/crop_20a7dc7fbd29d679b456fa0f77bd9525d.jpg");
                //图片的请求
                ImageRequest request1 = ImageRequestBuilder.newBuilderWithSource(uri1)
                        .setAutoRotateEnabled(true)//自动旋转
                        .build();
                //控制图片的加载
                DraweeController controller1 = Fresco.newDraweeControllerBuilder()
                        .setOldController(sdvFrescoResize.getController())
                        .setImageRequest(request1)
                        .build();
                //图片加载
                sdvFrescoResize.setController(controller1);

        9)修改图片

              为图片添加网格:

            (1)布局

    <com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/sdv_fresco_modify"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_gravity="center"
        android:layout_marginTop="48dp"
        fresco:placeholderImage="@drawable/atguigu_logo" />

            (2)代码

        //图片地址
        Uri uri = Uri.parse("https://pub-static.haozhaopian.net/static/web/site/features/cn/crop/images/crop_20a7dc7fbd29d679b456fa0f77bd9525d.jpg");
        //修改图片
        Postprocessor postprocessor = new BasePostprocessor() {
            @Override
            public String getName() {
                return super.getName();
            }

            //为图片添加网格
            @Override
            public void process(Bitmap bitmap) {
                super.process(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);
                    }
                }
            }
        };
        //请求图片
        ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                .setPostprocessor(postprocessor)
                .build();
        //图片加载的控制
        PipelineDraweeController controller = (PipelineDraweeController) Fresco.newDraweeControllerBuilder()
                .setOldController(sdvFrescoModify.getController())
                .setImageRequest(request)
                .build();
        //加载图片
        sdvFrescoModify.setController(controller);

        10)动态展示图片
            (1)布局

    <LinearLayout
        android:id="@+id/ll_fresco"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:orientation="vertical">

            (2)代码

初始化:

SimpleDraweeView simpleDraweeView = new SimpleDraweeView(this);
//设置宽高比
//宽度是高度的X倍
simpleDraweeView.setAspectRatio(1.0f);

 代码:

        //图片地址
        Uri uri = Uri.parse("http://img4q.duitang.com/uploads/item/201304/27/20130427043538_wAfHC.jpeg");
        //图片请求
        ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                .build();
        //图片加载的控制
        PipelineDraweeController controller = (PipelineDraweeController) Fresco.newDraweeControllerBuilder()
                .setOldController(simpleDraweeView.getController())
                .setImageRequest(request)
                .build();
        //加载图片
        simpleDraweeView.setController(controller);
        //添加图片到线性布局中
        llFresco.addView(simpleDraweeView);

设置宽高比为 1.0: 

设置宽高比为 2.0:

 


    八、注意事项(详见官网)

        1)问题处理
            1)重复的边界
            2)图片没有加载
            3)文件不可用
            4)OOM - 无法分配图片空间
            5)Bitmap太大导致无法绘制
            6)通过Logcat来判断原因
            7)启动日志
            8)查看日志
        2)一些陷阱
            1)不要使用 ScrollViews
            2)不要向下转换
            3)不要使用getTopLevelDrawable
            4)不要复用 DraweeHierarchies
            5)不要在多个DraweeHierarchy中使用同一个Drawable
            6)不要直接控制 hierarchy
            7)不要直接给 DraweeView 设置图片
            8)使用 DraweeView 时,请不要使用任何 ImageView 的属性
        3)为什么不支持wrap_content
        4)共享元素动画


    九、参考网站

        http://blog.csdn.net/u011771755/article/details/47608191
        https://github.com/NateRobinson/FrescoStudyDemo

 

图片框架的对比:

https://blog.csdn.net/zivensonice/article/details/51822968

https://juejin.im/entry/5af9aabf51882542bd69d0c0

Fresco虽然很强大,但是包很大,依赖很多,使用复杂,而且还要在布局使用SimpleDraweeView控件加载图片。相对而言Glide会轻好多,上手快,使用简单,配置方便,而且从加载速度和性能方面不相上下。对于一般的APP来说Glide是一个不错的选择,如果是专业的图片APP那么Fresco还是必要的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 图片选择框架是一种方便开发者在应用中实现图片选择、展示和处理功能的工具。在Android开发过程中,经常需要处理用户选择的图片,比如上传图片、展示图片列表、编辑图片等等,而使用图片选择框架可以大大简化这些操作。 目前比较常用的Android图片选择框架有很多,其中一些比较知名的包括Glide、Picasso、Fresco等。这些框架提供了丰富的功能,可以轻松加载网络图片、本地图片、相册图片等,支持图片大小的处理、缓存、压缩以及图片展示等。 使用这些框架,我们可以通过简单的代码实现图片选择功能。通过调用框架提供的接口,我们可以从相册中选择一张或多张图片,获取图片的路径或URI,然后进行后续的处理,比如上传图片到服务器、展示图片列表、编辑图片等。 另外,这些框架还提供了图片加载的功能,可以帮助我们快速加载要展示的图片,并且支持图片的缓存和压缩。通过使用这些框架,我们可以有效地避免加载大量图片时出现的内存溢出等问题,并且提高图片加载的速度和性能。 总之,Android图片选择框架为开发者提供了一种简单、高效的方式来处理图片选择和展示的需求,极大地简化了开发过程,同时也提高了用户体验。开发者可以根据具体的需求选择适合自己的图片选择框架,以提升应用的功能和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值