BitmapFactory.decodeResource加载图片缩小的原因及解决方法
2011-07-16 12:50
429 查看
声明:我是以2.0的代码为参考的,主要参考了BitmapFactory.java文件。 首先,在2.0应用中,res下有drawable-hdpi、drawable-mdpi、drawable-ldpi三个存放图片的文件夹,查资料看到如下描述:
这是分辨率的不同,H是高分辨率M是中L是低。
drawable-hdpi、drawable-mdpi、drawable-ldpi的区别:
(1)drawable-hdpi里面存放高分辨率的图片,如WVGA(480x800),FWVGA(480x854)
(2)drawable-mdpi里面存放中等分辨率的图片,如HVGA(320x480)
(3)drawable-ldpi里面存放低分辨率的图片,如QVGA(240x320) 开始不太理解,所以,看完代码后,先做了个实验,在三个文件夹下分别放入图片,通过下面的测试代码:
分别调用三个文件夹中的资源,打印分别为:240、160、120.
为什么看这个值呢?先看看我们调用的decodeResource方法在BitmapFactory.java中的实现:
接着看decodeResourceStream方法:
里面用到了value的density值来判断opts的inDensity的设置。
所以说,当我们从三个文件夹中获取资源的时候opts.inDensity的值分别会被设置成240、160、和120.
decodeResourceStream方法在对opts.inDensity设置之后,又进行了opts.inTargetDensity的设置,当其值为0的时候,会对其赋值。
如果,在测试函数中加入Log.d("LuoYer","densityDpi:"+resources.getDisplayMetrics().densityDpi);在我的板子上会打印值160.
那么,opts的inDensity和inTargetDensity对解析图片有什么关系呢?
通过decodeStream方法,最后会调用到finishDecode方法(此处仅列出计算示意,详细代码请查看BitmapFactory.java),其中,有在创建返回图片时设置缩放比例的计算:
最后的scale,就是缩放比例了,所以说,如果我们把图片资源放在了drawable-hdpi中,opts.inDensity的值为240,
而opts.inTargetDensity为0的情况下,会被设置为160.这样,返回的图片就会按2/3(160/240)的比例被缩放了。
而在drawable-mdpi中的图片,就不会被缩小。
当然,这也是以resources.getDisplayMetrics().densityDpi的值为基础的。
==============================================================================
原因已经清楚了,那么,怎样解决呢?
有看到说:把图片放到drawable-mdpi中就可以了。当然,在我前面叙述的情况下是可以的,但如果resources.getDisplayMetrics().densityDpi的值变化了,还会产生缩放的情况。
由于最后的图片创建用到了scale,那么,我们只需要保持density和targetDensity的一致,就可以避免缩放了,所以,我封装了一个解析函数:
这样,无论图片放在哪个文件夹里,都可以不必担心会被缩放了。
这是分辨率的不同,H是高分辨率M是中L是低。
drawable-hdpi、drawable-mdpi、drawable-ldpi的区别:
(1)drawable-hdpi里面存放高分辨率的图片,如WVGA(480x800),FWVGA(480x854)
(2)drawable-mdpi里面存放中等分辨率的图片,如HVGA(320x480)
(3)drawable-ldpi里面存放低分辨率的图片,如QVGA(240x320) 开始不太理解,所以,看完代码后,先做了个实验,在三个文件夹下分别放入图片,通过下面的测试代码:
private int getTargetDensityByResource(Resourcesresources, int id){ |
TypedValuevalue= new TypedValue(); |
resources.openRawResource(id,value); |
Log.d( "LuoYer" , "value.density:" +value.density); |
return value.density; |
} |
为什么看这个值呢?先看看我们调用的decodeResource方法在BitmapFactory.java中的实现:
public static BitmapdecodeResource(Resourcesres, int id,Optionsopts){ |
Bitmapbm= null ; |
InputStreamis= null ; |
try { |
final TypedValuevalue= new TypedValue(); |
is=res.openRawResource(id,value); |
bm=<STRONG>decodeResourceStream</STRONG>(res,value,is, null ,opts); |
} catch (Exceptione){ |
} finally { |
try { |
if (is!= null )is.close(); |
} catch (IOExceptione){} |
} |
return bm; |
} |
public static BitmapdecodeResourceStream(Resourcesres,TypedValuevalue, |
InputStreamis,Rectpad,Optionsopts){ |
if (opts== null ){ |
opts= new Options(); |
} |
if (opts.inDensity== 0 &&value!= null ){ |
final int density=value.density; |
if (density==TypedValue.DENSITY_DEFAULT){ |
opts.inDensity=DisplayMetrics.DENSITY_DEFAULT; |
} else if (density!=TypedValue.DENSITY_NONE){ |
opts.inDensity=density; |
} |
} |
if (opts.inTargetDensity== 0 &&res!= null ){ |
opts.inTargetDensity=res.getDisplayMetrics().densityDpi; |
} |
return decodeStream(is,pad,opts); |
} |
所以说,当我们从三个文件夹中获取资源的时候opts.inDensity的值分别会被设置成240、160、和120.
decodeResourceStream方法在对opts.inDensity设置之后,又进行了opts.inTargetDensity的设置,当其值为0的时候,会对其赋值。
如果,在测试函数中加入Log.d("LuoYer","densityDpi:"+resources.getDisplayMetrics().densityDpi);在我的板子上会打印值160.
那么,opts的inDensity和inTargetDensity对解析图片有什么关系呢?
通过decodeStream方法,最后会调用到finishDecode方法(此处仅列出计算示意,详细代码请查看BitmapFactory.java),其中,有在创建返回图片时设置缩放比例的计算:
final int density=opts.inDensity; |
final int targetDensity=opts.inTargetDensity; |
float scale=targetDensity/( float )density; |
而opts.inTargetDensity为0的情况下,会被设置为160.这样,返回的图片就会按2/3(160/240)的比例被缩放了。
而在drawable-mdpi中的图片,就不会被缩小。
当然,这也是以resources.getDisplayMetrics().densityDpi的值为基础的。
==============================================================================
原因已经清楚了,那么,怎样解决呢?
有看到说:把图片放到drawable-mdpi中就可以了。当然,在我前面叙述的情况下是可以的,但如果resources.getDisplayMetrics().densityDpi的值变化了,还会产生缩放的情况。
由于最后的图片创建用到了scale,那么,我们只需要保持density和targetDensity的一致,就可以避免缩放了,所以,我封装了一个解析函数:
private BitmapdecodeResource(Resourcesresources, int id){ |
TypedValuevalue= new TypedValue(); |
resources.openRawResource(id,value); |
BitmapFactory.Optionsopts= new BitmapFactory.Options(); |
opts.inTargetDensity=value.density; |
return BitmapFactory.decodeResource(resources,id,opts); |
} |
相关文章推荐
- Android编程之BitmapFactory.decodeResource加载图片缩小的原因及解决方法
- BitmapFactory.decodeResource加载图片缩小的原因及解决方法
- BitmapFactory.decodeResource加载图片缩小的原因及解决方法
- [转]Android编程之BitmapFactory.decodeResource加载图片缩小的原因及解决方法
- BitmapFactory.decodeResource加载图片缩小的原因及解决方法
- BitmapFactory.decodeResource加载图片缩小的原因及解决方法
- BitmapFactory.decodeResource加载图片缩小的原因及解决方法
- BitmapFactory.decodeResource加载图片缩小的原因及解决方法
- BitmapFactory.decodeResource加载图片缩小的原因及解决方法
- BitmapFactory.decodeResourcel加载图片缩小的原因和解决办法
- Android(decode文件转成bitmap)使用BitmapFactory.Options解决加载大图片内存溢出
- 解决BitmapFactory.decodeResource时出现图片缩放的问题
- 安卓方法——BitmapFactory.decodeResource()
- Android使用BitmapFactory.Options解决加载大图片内存溢出问题
- android 通过bitmapfactory得到图片真实像素的方法,以及没有得到真实像素的原因
- Android使用BitmapFactory.Options解决加载大图片内存溢出问题
- BitmapFactory.decodeResource 获取图片宽与高
- Android使用BitmapFactory.Options解决加载大图片内存溢出问题
- BitmapFactory.Options 解决加载大图片OOM
- Android使用BitmapFactory.Options解决加载大图片内存溢出问题