Android中BitmapFactory.Options详解

原文地址:这里--->http://blog.csdn.net/haozipi/article/details/47183543?ref=myread

Android中,BitmapFactory相信大家都很熟悉了,这个类里面的所有方法都是用来解码创建一个Bitmap,其中有一个重要的类是Options,此类用于解码Bitmap时的各种参数控制,那这里面的各种参数都是什么含义呢?今天我们就来重点解读几个参数。


inJustDecodeBounds

如果将这个值置为true,那么在解码的时候将不会返回bitmap,只会返回这个bitmap的尺寸。这个属性的目的是,如果你只想知道一个bitmap的尺寸,但又不想将其加载到内存时。这是一个非常有用的属性。


inSampleSize

这个值是一个int,当它小于1的时候,将会被当做1处理,如果大于1,那么就会按照比例(1 / inSampleSize)缩小bitmap的宽和高、降低分辨率,大于1时这个值将会被处置为2的倍数。例如,width=100,height=100,inSampleSize=2,那么就会将bitmap处理为,width=50,height=50,宽高降为1 / 2,像素数降为1 / 4。


inPreferredConfig

这个值是设置色彩模式,默认值是ARGB_8888,在这个模式下,一个像素点占用4bytes空间,一般对透明度不做要求的话,一般采用RGB_565模式,这个模式下一个像素点占用2bytes。


inPremultiplied

这个值和透明度通道有关,默认值是true,如果设置为true,则返回的bitmap的颜色通道上会预先附加上透明度通道。


inDither

这个值和抖动解码有关,默认值为false,表示不采用抖动解码。如果想知道什么是抖动解码,请参看我下面:

-------------------------------- Android中的抖动解码(inDither)-----------Start-------------------------------


Android中的BitmapFactory.Options中有一个属性值是inDither,这个值表示是否采用抖动解码,那什么叫抖动解码呢,今天我们就来详细解说一下。


Bitmap的解码是根据它所记录的节点,依照一定算法,来补充两个节点之间的数据,可以理解为补充其中像素点的颜色,那么在解码的时候肯定会和当前所采用的颜色模式有关,很直观的说,采用32位的肯定比16位的颜色要多,自然展现的图像会看起来更好。


如果一张颜色很丰富的图,用一个位数比较低的颜色模式来解码的话,那么一个直观的感觉就是颜色不够用,那么这张图解出来之后,在一些颜色渐变的区域上就会有一些很明显的断裂色带,这个很好解释,因为一些丰富的颜色在位数较低的颜色模式下并没有,那么只能用相近的填充,可能一大片都没有,那么一大片都用这一个颜色填充,就形成了断裂色带。


如果采用抖动解码,那么就会在这些色带上采用随机噪声色来填充,目的是让这张图显示效果更好,色带不那么明显。


看下面的例子:


很明显,左边的更平滑一点,右边的会有一些色带,如果不想有这些色带,那么就需要采用抖动解码。



-------------------------------- Android中的抖动解码(inDither)------------End--------------------------------


inDensity

表示这个bitmap的像素密度(对应的是DisplayMetrics中的densityDpi,不是density)。


inTargetDensity

表示要被画出来时的目标像素密度(对应的是DisplayMetrics中的densityDpi,不是density)。


inScreenDensity

表示实际设备的像素密度(对应的是DisplayMetrics中的densityDpi,不是density)。


inScaled

设置这个Bitmap是否可以被缩放,默认值是true,表示可以被缩放。


ps:inDensity,inTargetDensity,inScreenDensity三个值的具体关系请参看我下面:

--------------------------------------inDensity,inTargetDensity,inScreenDensity---------start-----------------------


这三个属性值在Bitmap和BitmapFactory中都有不同程度的出现,其中Bitmap中只有mDensity(对应inDensity),BitmapFactory中这三个都有,那么可以知道这三个值主要是在BitmapFactory中活动,于是我就查看了BitmapFactory中的源码,从而知道了这三个值的目的是为了确定这个Bitmap的宽高和density

下面我们从源码角度来分析一下,首先,这个Bitmap通过BitmapFactory创建出来一般经历两个方法,一个是解码的native方法,一个是BitmapFactory中的内部方法setDensityFromOptions。参看以下源码:

[java]  view plain  copy
  1. try {  
  2.             bm = nativeDecodeByteArray(data, offset, length, opts);  
  3.   
  4.             if (bm == null && opts != null && opts.inBitmap != null) {  
  5.                 throw new IllegalArgumentException("Problem decoding into existing bitmap");  
  6.             }  
  7.             setDensityFromOptions(bm, opts);  
  8.         } finally {  
  9.             Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);  
  10.         }  

我们先来分析native方法,以nativeDecodeByteArray方法为例:

引用摘自http://blog.csdn.net/bigconvience/article/details/27054639的nativeDecodeByteArray方法源码片段:

可以看到此方法中调用了doDecode方法,我们再来看doDecode方法:



通过源码可以发现,inDensity,inTargetDensity,inScreenDensity这三个值的主要目的就是确定这个Bitmap的是否会被缩放,如果被缩放,缩放之后的宽高是多少。


再来看setDensityFromOptions这个方法的源码:

[java]  view plain  copy
  1. /** 
  2.      * Set the newly decoded bitmap's density based on the Options. 
  3.      */  
  4.     private static void setDensityFromOptions(Bitmap outputBitmap, Options opts) {  
  5.         if (outputBitmap == null || opts == nullreturn;  
  6.   
  7.         final int density = opts.inDensity;  
  8.         if (density != 0) {  
  9.             outputBitmap.setDensity(density);  
  10.             final int targetDensity = opts.inTargetDensity;  
  11.             if (targetDensity == 0 || density == targetDensity || density == opts.inScreenDensity) {  
  12.                 return;  
  13.             }  
  14.   
  15.             byte[] np = outputBitmap.getNinePatchChunk();  
  16.             final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np);  
  17.             if (opts.inScaled || isNinePatch) {  
  18.                 outputBitmap.setDensity(targetDensity);  
  19.             }  
  20.         } else if (opts.inBitmap != null) {  
  21.             // bitmap was reused, ensure density is reset  
  22.             outputBitmap.setDensity(Bitmap.getDefaultDensity());  
  23.         }  
  24.     }  
从setDensityFromOptions方法中可以得知,会根据Options中的inDensity,inTargetDensity,inScreenDensity三个值和是否被缩放标识inScaled来确定这个Bitmap的mDensity(对应inDensity)。

从以上的分析可以得知,inDensity,inTargetDensity,inScreenDensity这三个值的目的就是为了确定这个Bitmap的宽高和density



--------------------------------------inDensity,inTargetDensity,inScreenDensity----------end-----------------------


inPurgeableinInputShareable

这两个值一般是一起使用,设置为true时,前者表示空间不够是否可以被释放,后者表示是否可以共享引用。这两个值在Android5.0后被弃用。


inPreferQualityOverSpeed

这个值表示是否在解码时图片有更高的品质,仅用于JPEG格式。如果设置为true,则图片会有更高的品质,但是会解码速度会很慢。


outWidthoutHeight

表示这个Bitmap的宽和高,一般和inJustDecodeBounds一起使用来获得Bitmap的宽高,但是不加载到内存。



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值