inDensity,inTargetDensity,inScreenDensity关系详解

来源:互联网 发布:阿里巴巴排名软件 编辑:程序博客网 时间:2024/05/21 01:42
如果接触Android中的Bitmap较深的话,肯定会知道标题上的这三个属性值,那么这三个属性值的关系和作用是什么呢?下面我们就来详细解读一下。

这三个属性值在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

原创粉丝点击