Glide加载图片缩放模式

前不久做一个水平图片滑动列表选择,效果类似于QQ发送图片。因为图片的长宽比不一致,而高度是固定的,所以就要对图片进行特殊拉伸。所以就看了下Glide拉伸这一块的源码。废话不多说了,下面开始总结。

平时我们用BitmapFactory进行加载较大图片时候,往往先通过inJustDecodeBounds方式解析出图片宽高,再结合ImageView宽高计算inSampleSize(即缩放比例),然后再“按需”加载bitmap,并显示出来。

那在Glide中是如何实现拉伸的呢?

其实Glide中实现也是上述思路,只是封装起来了。Glide负责计算缩放比例并decode的类是Downsampler,其中的getRoundedSampleSize 就负责计算缩放比例的。

public abstract class Downsampler implements BitmapDecoder<InputStream>{//这个方法decode图片得到bitmap,其实最终也会调用BitmapFactory.decode()方法@Overridepublic Bitmap decode(InputStream is, BitmapPool pool, int outWidth, int outHeight, DecodeFormat decodeFormat) {...省略...//这里计算缩放比例final int sampleSize = getRoundedSampleSize(degreesToRotate, inWidth, inHeight, outWidth, outHeight);//正式解析final Bitmap downsampled = downsampleWithSize(invalidatingStream, bufferedStream, options, pool, inWidth, inHeight, sampleSize,decodeFormat);...省略...}...//计算缩放比例private int getRoundedSampleSize(int degreesToRotate, int inWidth, int inHeight, int outWidth, int outHeight) {int targetHeight = outHeight == Target.SIZE_ORIGINAL ? inHeight : outHeight;int targetWidth = outWidth == Target.SIZE_ORIGINAL ? inWidth : outWidth;final int exactSampleSize;//注意下面的getSampleSize(),这个才是根据图片和Taget宽高计算缩放比例的。这个方法在下面有if (degreesToRotate == 90 || degreesToRotate == 270) {exactSampleSize = getSampleSize(inHeight, inWidth, targetWidth, targetHeight);} else {exactSampleSize = getSampleSize(inWidth, inHeight, targetWidth, targetHeight);}final int powerOfTwoSampleSize = exactSampleSize == 0 ? 0 : Integer.highestOneBit(exactSampleSize);// Although functionally equivalent to 0 for BitmapFactory, 1 is a safer default for our code than 0.return Math.max(1, powerOfTwoSampleSize);}//getSampleSize,这个核心方法是抽象方法,根据图片宽高(inWith和inHeight)和// Target宽高(outWidth和outHeight)来计算缩放比例protected abstract int getSampleSize(int inWidth, int inHeight, int outWidth, int outHeight);
}

如上代码展示,最核心的抽象方法getSampleSize才是决定如何缩放的,而Downsampler目前仅提供3种实现,分别是:

  • AT_LEAT:这个是默认方式,用比例差距小的边作为缩放基准
public static final Downsampler AT_LEAST = new Downsampler() {@Overrideprotected int getSampleSize(int inWidth, int inHeight, int outWidth, int outHeight) {return Math.min(inHeight / outHeight, inWidth / outWidth);}...};
  • AT_MOST:用比例差距大的边作为缩放基准
public static final Downsampler AT_MOST = new Downsampler() {@Overrideprotected int getSampleSize(int inWidth, int inHeight, int outWidth, int outHeight) {int maxIntegerFactor = (int) Math.ceil(Math.max(inHeight / (float) outHeight,inWidth / (float) outWidth));int lesserOrEqualSampleSize = Math.max(1, Integer.highestOneBit(maxIntegerFactor));return lesserOrEqualSampleSize << (lesserOrEqualSampleSize < maxIntegerFactor ? 1 : 0);}...};
  • NONE不缩放,采用原始比例。即当我们使用Target.SIZE_ORIGINAL作为Target宽高的时候
public static final Downsampler NONE = new Downsampler() {@Overrideprotected int getSampleSize(int inWidth, int inHeight, int outWidth, int outHeight) {return 0;}...
};

​ 这三种方式,在Glide加载图片时如何应用的呢? 我们在Glide.with(context).load(path).asBitmap() 时会得到BitmapRequestBuilder,下面是它的部分代码。可以得知调用它的approximate() 、atMost() 、asIs()分别对应上面的AT_LEAST、ATMOST、以及None

public class BitmapRequestBuilder<ModelType, TranscodeType>extends GenericRequestBuilder<ModelType, ImageVideoWrapper, Bitmap, TranscodeType> implements BitmapOptions {public BitmapRequestBuilder<ModelType, TranscodeType> approximate() {return downsample(Downsampler.AT_LEAST);}//指定不缩放  public BitmapRequestBuilder<ModelType, TranscodeType> asIs() {return downsample(Downsampler.NONE);}public BitmapRequestBuilder<ModelType, TranscodeType> atMost() {return downsample(Downsampler.AT_MOST);}//遗憾这个是私有方法,不能自定义private BitmapRequestBuilder<ModelType, TranscodeType> downsample(Downsampler downsampler) {this.downsampler = downsampler;imageDecoder = new StreamBitmapDecoder(downsampler, bitmapPool, decodeFormat);super.decoder(new ImageVideoBitmapDecoder(imageDecoder, videoDecoder));return this;}}

到此, Glide的缩放原理就比较清楚了。遗憾的是,downsample是私有方法,这就意味着我们不能自定义一个Downsampler。不知是否还有其他地方可以设置

Glide加载图片缩放模式相关推荐

  1. Glide加载图片模糊问题

    关于Glide加载图片模糊 需求:1.整张界面展示大图,可缩放.2.在无网络情况下,展示缓存图片:3.大图要清晰. 1.缩放控件可以直接从网络上找,遍地的自定义view.由于项目里面用的有环信,所以直 ...

  2. Android框架之路——Glide加载图片(结合RecyclerView、CardView)

    Android框架之路--Glide加载图片 一.简介: 在泰国举行的谷歌开发者论坛上,谷歌为我们介绍了一个名叫 Glide 的图片加载库,作者是bumptech.这个库被广泛的运用在google的开 ...

  3. Android --- Glide加载图片时候调用asBitmap()方法的时候总是报错,点不出来?

    今天写Glide加载图片的时候,网上给的例子全都是这样写的 很明显.asBitmap()在load后面,放到我的代码里就会报错,如下: 最后查了半天度娘才发现要在with()之后添加asBitmap( ...

  4. Android Glide加载图片成圆形

    今天,简单讲解android使用glide加载图片成圆形. 这个很简单,因为之前需要在RecyclerView里加载圆形图片,所以在网上查找了资料,很简单就解决了. 1.导入依赖 implementa ...

  5. android glide圆形图片,Android Glide加载图片成圆形

    释放双眼,带上耳机,听听看~! 今天,简单讲解android使用glide加载图片成圆形. 这个很简单,因为之前需要在RecyclerView里加载圆形图片,所以在网上查找了资料,很简单就解决了. 1 ...

  6. 关于 Glide 加载图片圆角问题

    在使用 Glide 加载图片是,当我们在显示一张图片的时候,想让他等比例缩放到ImageView的大小,又想这张图片实现矩形圆角,我们的常规的写法就是: Glide.with(context).loa ...

  7. Android Glide加载图片、网络监听、设置资源监听

    Glide加载图片.加载进度监听 前言 正文 一.项目配置 二.显示网络图片 三.添加设置资源监听 四.添加设置资源监听 五.添加加载进度条 六.封装工具类 七.源码 总结 前言   在日常开发中使用 ...

  8. Glide加载图片变形,刷新后恢复正常

    在listview,recycleview使用glide加载图片的时候出现第一次加载的图片略大,刷新后即可恢复正常的现象,影响用户体验 解决的方法: 首先将自己的imageview的scaleType ...

  9. RecyclerView 滑动时不让 Glide 加载图片

    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {@Overridepublic void onScrollS ...

  10. Glide加载图片尺寸不对的问题

    问题: 因为icon_missing_image这张占位图尺寸导致问题: 如果Imageview中默认的占位图片大小没有填满Imageview,比如Imageview100*80,但是给Imagevi ...

最新文章

  1. Android应用点击两次back退出
  2. python入门题目及答案_Python基础自测题答案和基础知识梳理
  3. Python测试演讲稿收集
  4. 威联通NAS通过宝塔面板实现域名统一端口访问
  5. html引用c 变量,Y.A.K.E
  6. [剑指offer][JAVA]面试题第[05]题[替换空格][StringBuilder/Buffer]
  7. python执行语句转换成str_python3.x,_python3.4.3如何转换str字符串?,python3.x - phpStudy...
  8. magento左栏添加筛选Filtering options on Left-Navigation Menu in Products List Page
  9. 技术无价,“悟”有所值——UCan下午茶这一年
  10. C语言项目大作业万历年,用C语言编写万历,详细代码.doc
  11. CentOS release5.5 (Final)搭建个人本地网站
  12. 关于重装系统后,电脑出现提示许可证过期的解决方案
  13. 让电脑「读懂」你的思想——java工程师的职业规划
  14. VB类计算机专业毕业设计题目
  15. 计算机技术专硕学哪些课程,计算机专业考研需要考哪些科目
  16. java pfx_java读取pfx或P12格式的个人交换库公私钥
  17. html那种折叠文字内容怎么实现,html+css实现文字折叠特效实例
  18. 离散数学在计算机科学中的应用
  19. python语法基础-cPickle.dump使用
  20. C#treeview树形菜单

热门文章

  1. 第一章 80C51单片机概述
  2. 2022-2028年中国沉香行业发展模式分析及投资趋势预测报告
  3. 网络通信中 TCP 产生 RST 的三个条件分析
  4. Chrome 浏览器翻译停服!改Hosts也失效!还有这些解决方案
  5. 对于Biotin-LC-NHS Estercas:72040-63-2与伯氨基 (-NH2) 反应的作用有哪些?
  6. VMWare 虚拟机网络共享给宿主机
  7. iphone视频照片恢复
  8. 8.(高级)CSS形状之:菱形图片
  9. pcie gen3 bios设置_唯一还在认真做BIOS的大陆板卡厂商!七彩虹iGame Z490 Vulcan X V20评测...
  10. Fatal signal 11 (SIGSEGV) at 0x00000014 (code=1), thread 29925 (cloud.diversion)