LotusLoveNature

日常工作,生活小记

关于display和BitmapFactory.Options

public static Bitmap decodeResource(Resources res, int id)这个android的方法大家都不陌生,但是其中的小秘密却是今天才发现。

发现时机:手机分辨率为hdpi的,传入一个resid,对于的图片是1440x1280的,但是放在drawable下面了。通过public Bitmap decodeResource(Resources res, int resId, Options opts)方法decode出来的图片大小为2160x1920,不是期望的1440x1280.

通过查看源码和尝试,发现decodeResource方法会对图片做一个scale,这个scale的值=options.inTargetDensity/options.inDensity

那么这个options是什么呢?它就是BitmapFactory.Options,上面两个值默认都为0,在decodeResource过程中被赋值。这里说下inDensity,inTargetDensity, outWidth, outHeight这几个属性。

1. inDensity,它的值是TypedValue 中的value赋值的,是根据resource也就是图片获取到的,跟了下会到native层,但是经验得出这个值是和图片所在的drawable dpi有关,比如/drawable默认为160,/drawable-xxh为480.

2. inTargetDensity,它的值是有getResources().getDisplayMetrics().density获得,这个读取的是设备的屏幕密度值。

那我们可以看出文章开头的问题所在,options就算没有以参数形式带入,上面依然成立,因为内部如果发现options为null,会自己new一个,后续都一样,scale=240/160=1.5.  这里的240是因为手机是xhdpi的,160是因为放在drawable下面。所以得出的小为,1440*scale,1280*scale,得出的结果和上面正好一样。

3.这里想说一下outWidth,outHeight,表示图片decode出来的宽高,比如前面得到的2160x1920。这个很明显了。但是有个参数不得不说一下,options.inJustDecodeBounds,这个参数会影响outWidth,outHeight的结果,如是true,表示不生成bitmap,decodeResource返回的为null,但是可以得到图片的outWidth,outHeight,这个outWidth,outHeight是不依赖与density的,即上面问题,如果提前设置inJustDecodeBounds的话,得到的w和h不管是否放错资源drawable目录,都是1440x1280.但是如果inJustDecodeBounds为false,那么decode出来的bitmap不会null,并且outWidth,outHeight就是经过处理的大小。当然,inJustDecodeBounds默认为false。

 

评论
©LotusLoveNature | Powered by LOFTER