如果想要decodeFile与decodeResource一样,我这里只需要改变Options的参数,将
op.inDensity = TypedValue.DENSITY_NONE;
op.inTargetDensity = TypedValue.DENSITY_NONE ;
设置成上面的就可以了。代表不进行像素的
inDensity——用于位图的像素压缩比
inTargetDensity——用于目标位图的像素压缩比(要生成的位图)
最近在项目中遇到的问题,一种是放在drawable下的资源文件,一种为下载后复制到data/data目录下的文件,同样的分辨率,放入相同layout配置的ImageView中,显示的大小却不一样。查看代码后,逻辑并无不同的地方,唯一的区别是:读取图片文件资源的时候,读drawable下用的decodeResource方法,读data/data下用的decodeFile方法。用分辨率320px*569px的手机执行的效果是,decodeResource方法读出的图片比decodeFile大一点,debug出的为放大了1.5倍。就现象而言,decodeResource方法自己似乎做了scale处理。
于是翻看源码,得到执行两种方法时的调用次序:
decodeFile(String pathName) ->decodeFile(pathName, null) -> decodeStream(stream, null, opts)
decodeResource(res, id) -> decodeResource(res, id, null) -> decodeResourceStream(res, value, is, null, opts) -> decodeStream(is, pad, opts)
对比各自处理,不同点发生在decodeResource会调用的decodeResourceStream方法中
opts.inDensity设成了DisplayMetrics.DENSITY_DEFAULT 为160
opts.inTargetDensity设成res.getDisplayMetrics().densityDpi 为240
就字面意思,inTargetDensity正好是inDensity的1.5倍,查了SDK如下
opts.inDensity的解释
opts.inTargetDensity的解释
inDensity——用于位图的像素压缩比
inTargetDensity——用于目标位图的像素压缩比(要生成的位图)
inScaled——设置为true时进行图片压缩,从inDensity到inTargetDensity。
由上可知,decodeResourceStream方法根据手机屏幕的密度有一个缩放图片的过程,而decodeFile不会自动处理。为了避开这种差异性,将decodeFile方法的调用替换掉,先得到图片文件的InputStream,再直接调用decodeResourceStream,模拟decodeResource的操作。
其实,decodeResource中对图片文件的缩放可以理解成图片像素px与屏幕dip显示的转换,可为什么decodeFile没有做这一步?暂时不知道原因,可能是decodeResource多用于drawable下本app资源的读取,涉及到不同屏幕密度的区分吧。
另外关于DisplayMetrics的屏幕密度Density,官方的解释:
The logical density of the display. This is a scaling factor for the Density Independent Pixel unit, where one DIP is one pixel on an approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen), providing the baseline of the system's display. Thus on a 160dpi screen this density value will be 1; on a 120 dpi screen it would be .75; etc.
This value does not exactly follow the real screen size (as given by xdpi
andydpi
, but rather is used to scale the size of the overall UI in steps based on gross changes in the display dpi. For example, a 240x320 screen will have a density of 1 even if its width is 1.8", 1.3", etc. However, if the screen resolution is increased to 320x480 but the screen size remained 1.5"x2" then the density would be increased (probably to 1.5).
上面一段不是太明白,自己的理解:屏幕密度与手机硬件有关,而这个Density是一个倍率值,相同的分辨率屏幕尺寸越小,密度就越大,dip与密度有关系,官方解释也说了“在160dip的屏幕上,1dip=1px”。它常用于程序中dip,px之间的转换
关于dip,px,屏幕密度的理解,可结合下面的内容理解(注:以下内容均转载自 http://blog.csdn.net/cgaanns/article/details/6180618)