例:
http://p1.so.qhmsg.com/bdr/_240_/t0179d442a840b6df46.gif
http://img.1985t.com/uploads/attaches/2017/12/141013-eSnS9sO.jpg
https://www.zhaoapi.cn/images/1524972479241gaga_icon.jpg
1.Fresco的环境搭建
(1)在项目的build.grade文件里添加依赖
(注意:因为Fresco进行了包的拆分,用到哪个功能就添加对应的依赖,可以减少APP的体积)
dependencies { //Fresco,无论使用哪个模块的功能,都必须要添加的基础依赖 compile 'com.facebook.fresco:fresco:0.14.1' //下面的依赖根据需求,用到哪个模块,就导入对应的依赖即可. // 仅支持 WebP 静态图,需要添加 compile 'com.facebook.fresco:webpsupport:0.14.1' // 支持 GIF 动图,需要添加 compile 'com.facebook.fresco:animated-gif:0.14.1' // 支持 WebP 静态图及 WebP 动图,需要添加 compile 'com.facebook.fresco:animated-webp:0.14.1' compile 'com.facebook.fresco:webpsupport:0.14.1' // 在 API < 14 上的机器支持 WebP 时,需要添加 compile 'com.facebook.fresco:animated-base-support:0.14.1' }(2)在application中初始化Fresco(记得在清单文件里配置application)
Fresco.initialize(this);
(3)配置网络权限
<uses-permission android:name="android.permission.INTERNET"/>(4)在xml布局文件中,加入命名空间
<LinearLayout xmlns:fresco="http://schemas.android.com/apk/res-auto">(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" />
2.Fresco的基本使用
(1)在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需要进行替换(因为Fresco底层网络用的是okhttp,不做修改会出现jar包冲突) OkHttp2版本:compile "com.facebook.fresco:imagepipeline-okhttp:0.12.0+" OkHttp3版本::compile "com.facebook.fresco:imagepipeline-okhttp3:0.12.0+"
3.根据URI的地址,带进度条加载一个网络图片
//所要加载图片的网址 Uri uri = Uri.parse("http://assets.kgc.cn/upload/openteacher/20160831/1472636067718985.jpg"); //创建Builder对象,一般创建出参数对象 GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(getResources()); //创建参数对象,设置其样式为进度条 GenericDraweeHierarchy hierarchy = builder.setProgressBarImage(new ProgressBarDrawable()).build(); //将参数对象设置给图片控件 sdv_fresco_spimg.setHierarchy(hierarchy); //控件加载图片,参数:网络图片的网址. sdv_fresco_spimg.setImageURI(uri);
4.对图片进行不同的裁剪
创建出成员变量的GenericDraweeHierarchyBuilder
builder = new GenericDraweeHierarchyBuilder(getResources());
//根据点击事件,对图片执行不同的裁剪 @Override public void onClick(View v){ switch (v.getId()) { // 居中,无缩放 case R.id.bt_fresco_center: // 设置描述 tv_fresco_explain.setText("居中,无缩放"); // 样式设置,使图片只显示中间的部分 GenericDraweeHierarchy CENTER= builder.setActualImageScaleType(ScalingUtils.ScaleType.CENTER).build(); // 显示图片 imageDisplay(CENTER); break; // 保持宽高比缩小或放大,使得两边都大于或等于显示边界(也就是裁剪成正方形)。以中间的点为图片中心 case R.id.bt_fresco_centercrop: // 设置描述 tv_fresco_explain.setText("保持宽高比缩小或放大,使得两边都大于或等于显示边界。居中显示"); // 样式设置,使图片按比例缩小或放大,且裁剪成正方形. GenericDraweeHierarchy CENTER_CROP =builder.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_CROP).build(); // 图片显示 imageDisplay(CENTER_CROP); break; // 同centerCrop, 但居中点不是中点,而是指定的某个点,这里设置为图片的左上角那点 case R.id.bt_fresco_focuscrop: // 设置描述 tv_fresco_explain.setText("同centerCrop, 但居中点不是中点,而是指定的某个点,这里我设置为图片的左上角那点"); //指定中心点位置 PointF point = new PointF(0,0); //根据指定的点设置为图片中心,使图片按比例缩小或放大,且裁剪成正方形. GenericDraweeHierarchy FOCUS_CROP= builder.setActualImageScaleType(ScalingUtils.ScaleType.FOCUS_CROP) .setActualImageFocusPoint(point).build(); // 图片显示 imageDisplay(FOCUS_CROP); break; //使两边都在显示边界内,居中显示。如果图尺寸大于显示边界,则保持长宽比缩小图片 case R.id.bt_fresco_centerinside: // 设置描述 tv_fresco_explain.setText("使两边都在显示边界内,居中显示。如果图尺寸大于显示边界,则保持长宽比缩小图片"); // 样式设置,使图片按比例显示在控件内, GenericDraweeHierarchy CENTER_INSIDE=builder.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_INSIDE).build(); // 图片显示 imageDisplay(CENTER_INSIDE); break; // 保持宽高比,缩小或者放大,使得图片完全显示在显示边界内。居中显示 case R.id.bt_fresco_fitcenter: // 设置描述 tv_fresco_explain.setText("保持宽高比,缩小或者放大,使得图片完全显示在显示边界内。居中显示"); // 样式设置,保持宽高比例,对图片进行缩或放,图片位置居中显示(效果和上面一种类似) GenericDraweeHierarchy FIT_CENTER =builder.setActualImageScaleType(ScalingUtils.ScaleType.FIT_CENTER).build(); // 图片显示 imageDisplay(FIT_CENTER); break; // 保持宽高比,缩小或者放大,使得图片完全显示在显示边界内,不居中,和显示边界左上对齐 case R.id.bt_fresco_fitstart: // 设置描述 tv_fresco_explain.setText("保持宽高比,缩小或者放大,使得图片完全显示在显示边界内,不居中,和显示边界左上对齐"); // 样式设置,保持宽高比例,对图片进行缩或放,图片位置,不居中,和显示边界左上对齐 GenericDraweeHierarchy FIT_START =builder.setActualImageScaleType(ScalingUtils.ScaleType.FIT_START).build(); // 图片显示 imageDisplay(FIT_START); break; // 保持宽高比,缩小或者放大,使得图片完全显示在显示边界内,不居中,和显示边界右下对齐 case R.id.bt_fresco_fitend: // 设置描述 tv_fresco_explain.setText("保持宽高比,缩小或者放大,使得图片完全显示在显示边界内,不居中,和显示边界右下对齐"); // 样式设置,保持宽高比例,对图片进行缩或放,图片位置,不居中,和显示边界右下对齐 GenericDraweeHierarchy FIT_END =builder.setActualImageScaleType(ScalingUtils.ScaleType.FIT_END).build(); // 图片显示 imageDisplay(FIT_END); break; // 不保持宽高比,填充满显示边界 case R.id.bt_fresco_fitxy: // 设置描述 tv_fresco_explain.setText("不保持宽高比,填充满显示边界"); // 样式设置,使图片填充整个控件,不保证宽高比例. GenericDraweeHierarchy FIT_XY= builder.setActualImageScaleType(ScalingUtils.ScaleType.FIT_XY).build(); // 图片显示 imageDisplay(FIT_XY); break; // 如要使用titlemode显示, 需要设置为none case R.id.bt_fresco_none: // 设置描述 tv_fresco_explain.setText("如要使用titlemode显示, 需要设置为none"); // 样式设置 GenericDraweeHierarchy hierarchy= builder.setActualImageScaleType(null).build(); // 图片显示 imageDisplay(hierarchy); break; } }
/** * 把得到的样式进行设置,加载出图片 * @param hierarchy */ private void imageDisplay(GenericDraweeHierarchyhierarchy) { // 加载图片 Uri uri = Uri.parse("http://img4q.duitang.com/uploads/item/201305/20/20130520115416_VrUUR.jpeg"); sdv_fresco_crop.setHierarchy(hierarchy); sdv_fresco_crop.setImageURI(uri); }
5.圆形图片和圆角图片
//加载图片的网址 uri = Uri.parse("http://img4q.duitang.com/uploads/item/201304/27/20130427043538_wAfHC.jpeg"); //builder对象用一个即可,在这里创建出成员变量 builder = new GenericDraweeHierarchyBuilder(getResources()); // 设置圆形图片 // 设置形状对象,形状为圆形 parames =RoundingParams.asCircle(); //创建设置参数,设置一个形状,把形状对象塞入 GenericDraweeHierarchy roundness= builder.setRoundingParams(parames).build(); //将参数对象设置给图片控件 sdv_fresco_circleandcorner.setHierarchy(roundness); //控件加载图片 sdv_fresco_circleandcorner.setImageURI(uri); // 设置圆角图片 //设置边角的弧度,使其为圆角 parames =RoundingParams.fromCornersRadius(50f); /* //设置图片控件的背景颜色 parames.setOverlayColor(getResources().getColor(android.R.color.holo_red_light));//覆盖层 //设置图片的边框颜色及边框的粗细 parames.setBorder(getResources().getColor(android.R.color.holo_blue_light),5);//边框*/ //这里的代码和设置圆形图片这一块代码是一种的,唯一不同就是对parames的设置. GenericDraweeHierarchy circularBead = builder.setRoundingParams(parames).build(); sdv_fresco_circleandcorner.setHierarchy(circularBead); // 加载图片 sdv_fresco_circleandcorner.setImageURI(uri);
6.渐进式展示图片(采用MVC的设计模式)
// 获取图片URL Uri uri = Uri.parse("http://img1.yulin520.com/news/8OIFWKCGZFR0O868X20V.jpg#586_616"); // 加载质量配置,为了实现节省CPU,随着图片下载的进行,下载完的扫描序列如下: 1, 4, 5, 10 /* 首次调用getNextScanNumberToDecode返回为2,因为初始时,解码的扫描数为0。 那么1将不会解码,下载完成4个扫描时,解码一次。下个解码为扫描数为6(5不会解码,10才会解码)*/ 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(Main3Activity.this).setProgressiveJpegConfig(jpegConfig).build(); // 创建 ImageRequest 对象. ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)//设置URL .setProgressiveRenderingEnabled(true)//打开渐进渲染 .build(); DraweeController draweeController =Fresco.newDraweeControllerBuilder() //必须要设置ImageRequest对象,里面包含了图片的网址. .setImageRequest(request) //开启用户点击重新加载图片的功能 .setTapToRetryEnabled(true) //会复用以前的对象,可以节省内存. .setOldController(my_image_view.getController()) .build(); // 1设置加载的控制 my_image_view.setController(draweeController);
7.GIF动画图片
//请求GIF动画,采用MVC的设计模式(注意加载GIF动画还要添加依赖) /* 支持 GIF 动图,需要添加:compile 'com.facebook.fresco:animated-gif:0.14.1' */ //GIF动画网址,加载需要一段时间 Uri uri = Uri.parse("http://www.sznews.com/humor/attachement/gif/site3/20140902/4487fcd7fc66156f51db5d.gif"); DraweeController controller =Fresco.newDraweeControllerBuilder() .setUri(uri)//设置GIF网址 .setAutoPlayAnimations(false)//是否自动播放动画,false为不播放 .setOldController(sdv_fresco_gif.getController())//内存优化 .build(); sdv_fresco_gif.setController(controller); // 动画停止 //拿到动画对象 Animatable animatableStop = sdv_fresco_gif.getController().getAnimatable(); //进行非空及是否动画在播放判断 if(animatableStop != null &&animatableStop.isRunning()) { //动画在播放,停止动画播放 animatableStop.stop(); } // 动画开始 //拿到动画对象 Animatable animatableStart = sdv_fresco_gif.getController().getAnimatable(); //进行非空及是否动画在播放判断 if(animatableStart != null &&!animatableStart.isRunning()) { //动画停止播放,播放动画 animatableStart.start(); }
8.多图请求及图片复用
//多图请求及图片复用 // 先显示低分辨率的图,然后是高分辨率的图,MVC的设计模式 // 同一个图片,不同分辨率的两个URL地址 Uri lowUri = Uri.parse("http://img3.imgtn.bdimg.com/it/u=4045410176,95411995&fm=27&gp=0.jpg"); Uri highUri = Uri.parse("http://img.1985t.com/uploads/attaches/2017/12/141013-eSnS9sO.jpg"); // 控制加载图片 DraweeController controller =Fresco.newDraweeControllerBuilder() //一开始加载一个低分辨率的URL .setLowResImageRequest(ImageRequest.fromUri(lowUri)) //然后加载一个高分辨率的URL,你真正要加载的图片 .setImageRequest(ImageRequest.fromUri(highUri)) .build(); // 加载图片 my_image_view.setController(controller); // 本地缩略图预览 // 图片地址,参数1.File对象, 从手机手机SD卡里加载一张图片 Uri uri = Uri.fromFile(new File(Environment.getExternalStorageDirectory()+"/shuaige.jpg")); // 加载图片的请求 ImageRequest request =ImageRequestBuilder.newBuilderWithSource(uri) //开启缩略图预览模式 .setLocalThumbnailPreviewsEnabled(true) .build(); // 控制图片的加载 DraweeController preview =Fresco.newDraweeControllerBuilder() .setImageRequest(request) .build(); // 加载图片 my_image_view.setController(preview); //本地图片的复用 //在请求之前,还会去内存中请求一次图片,没有才会先去本地,最后去网络uri //本地准备复用图片的uri 如果本地这个图片不存在,会自动去加载下一个uri // 本地图片的地址 Uri uri1 = Uri.fromFile(new File(Environment.getExternalStorageDirectory()+"/shuaige.jpg")); //图片的网址 Uri uri2 = Uri.parse("http://img5.duitang.com/uploads/item/201312/03/20131203153823_Y4y8F.jpeg"); //创建ImageRequest对象,将其放入ImageRequest[]数组中. ImageRequest request1 =ImageRequest.fromUri(uri1); ImageRequest request2 =ImageRequest.fromUri(uri2); ImageRequest[] requests = {request1,request2}; // 控制加载图片 DraweeController reuse =Fresco.newDraweeControllerBuilder() //设置加载图片的顺序.参数ImageRequest[]数组 .setFirstAvailableImageRequests(requests) .setOldController(my_image_view.getController()) .build(); // 加载图片 my_image_view.setController(reuse);
9.图片加载监听
// 图片地址 Uri uri = Uri.parse("http://h.hiphotos.baidu.com/zhidao/pic/item/58ee3d6d55fbb2fbac4f2af24f4a20a44723dcee.jpg"); // 加载质量配置,为了实现节省CPU,随着图片下载的进行,下载完的扫描序列如下: 1, 4, 5, 10 /* 首次调用getNextScanNumberToDecode返回为2,因为初始时,解码的扫描数为0。 那么1将不会解码,下载完成4个扫描时,解码一次。下个解码为扫描数为6(5不会解码,10才会解码)*/ ProgressiveJpegConfig jpegConfig= new ProgressiveJpegConfig() { @Override public int getNextScanNumberToDecode(int scanNumber) { return scanNumber + 2; } @Override public QualityInfogetQualityInfo(int scanNumber) { boolean isGoodEnough =(scanNumber >= 5); return ImmutableQualityInfo.of(scanNumber,isGoodEnough, false); } }; //上面的和下面一行是固定代码.使用使复制粘贴即可 ImagePipelineConfig.newBuilder(this).setProgressiveJpegConfig(jpegConfig).build(); // 图片请求, ImageRequest request =ImageRequestBuilder.newBuilderWithSource(uri)//指定加载图片地址 .setProgressiveRenderingEnabled(true)////打开渐进渲染 .build(); // 图片加载的控制 DraweeController controller =Fresco.newDraweeControllerBuilder() .setOldController(sdv_fresco_listener.getController()) .setImageRequest(request) //设置监听器监听图片的加载 .setControllerListener(controllerListener) .build(); // 加载图片 sdv_fresco_listener.setController(controller); private ControllerListener controllerListener = new BaseControllerListener(){ // 加载图片完毕回调 @Override public void onFinalImageSet(Stringid, ImageInfo imageInfo, Animatable animatable) { super.onFinalImageSet(id,imageInfo, animatable); //图片信息对象非空判断 if (imageInfo == null) { return; } // 获取图片的质量信息 QualityInfo qualityInfo = imageInfo.getQualityInfo(); tv_fresco_listener.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 onIntermediateImageSet(Stringid, ImageInfo imageInfo) { super.onIntermediateImageSet(id,imageInfo); tv_fresco_listener2.setText("IntermediateImageSet image receiced"); } // 加载图片失败回调 @Override public void onFailure(Stringid, Throwable throwable) { super.onFailure(id,throwable); //这里的id参数就是图片加载失败的打印信息 tv_fresco_listener.setText("Error loading" + id); } };
10.修改内存中图片占用资源的大小
// 图片地址 Uri uri = Uri.parse("http://c.hiphotos.baidu.com/image/pic/item/962bd40735fae6cd21a519680db30f2442a70fa1.jpg"); //图片的请求 ImageRequest request =ImageRequestBuilder.newBuilderWithSource(uri) //重新设置这张图片的宽高.以便解决内存 .setResizeOptions(new ResizeOptions(50, 50)) .build(); // 控制图片的加载 PipelineDraweeController controller= (PipelineDraweeController) Fresco.newDraweeControllerBuilder() .setOldController(sdv_fresco_resize.getController()) .setImageRequest(request) .build(); // 加载图片 sdv_fresco_resize.setController(controller);
11.修改图片
// 图片地址 Uri uri = Uri.parse("http://c.hiphotos.baidu.com/image/pic/item/962bd40735fae6cd21a519680db30f2442a70fa1.jpg"); // 修改图片 Postprocessor postProcessor = new BasePostprocessor(){ //重新Postprocessor名称. @Override public StringgetName() { return "postProcessor"; } //具体的进行绘制,bitmap就是下载过来的图片,绘制红色点状网络 @Override public void process(Bitmapbitmap) { for (int x = 0; x < bitmap.getWidth(); x += 2) { for (int y = 0; y < bitmap.getHeight(); y += 2) { //给图片点设置颜色,参数X轴,Y轴,颜色 bitmap.setPixel(x, y, Color.RED); } } } }; // 创建图片请求 ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri) //对加载进行处理.参数就是处理的模型Postprocessor对象. .setPostprocessor(postProcessor) .build(); // 控制加载 PipelineDraweeController controller = (PipelineDraweeController)Fresco.newDraweeControllerBuilder() .setOldController(sdv_fresco_modify.getController()) .setImageRequest(request) .build(); // 加载图片 sdv_fresco_modify.setController(controller);
12.动态展示图片,也就是在java代码里添加控件
//创建控件 //创建Fresco加载图片的控件对象 simpleDraweeView = new SimpleDraweeView(this); // 设置控件对象的宽高比,必须设置,参数浮点型,大于1,则宽度是高度的几倍. simpleDraweeView.setAspectRatio(0.5f); //使用控件,并添加到布局中 // 图片的地址 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); // 将simpleDraweeView控件对象,添加到线性布局中 ll_fresco.addView(simpleDraweeView);