BitmapFactory: 通过Bitmap的getWidth和getHeight方法获取到的尺寸与实际尺寸不符的问题
问题
今天无意中发现了一个问题,通过Bitmap的getWidth和getHeight方法获取到的图片尺寸与实际的尺寸(1920*1080)不一致,后来更进一步发现,把这张图片分别放在raw、drawable-mdpi、drawable-hdpi、drawable-xhdpi、drawable-xxhdpi、drawable-xxxhdpi时,通过以上两个方法获取到的尺寸也都不一致。
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img_mac_os_x);
if (bitmap != null) {
Log.i("xp.chen", "decode bitmap width: "+bitmap.getWidth()+", bitmap height: "+bitmap.getHeight());
}
下面是把图片分别放在raw、drawable-mdpi、drawable-hdpi、drawable-xhdpi、drawable-xxhdpi、drawable-xxxhdpi时,通过Bitmap的getWidth()/getHeight()分别获取到的尺寸:
raw:I/xp.chen: decode bitmap width: 7680, bitmap height: 4320
drawable-mdpi:I/xp.chen: decode bitmap width: 7680, bitmap height: 4320
drawable-hdpi:I/xp.chen: decode bitmap width: 5120, bitmap height: 2880
drawable-xhdpi:I/xp.chen: decode bitmap width: 3840, bitmap height: 2160
drawable-xxhdpi:I/xp.chen: decode bitmap width: 2560, bitmap height: 1440
drawable-xxxhdp:I/xp.chen: decode bitmap width: 1920, bitmap height: 1080
为什么会这样
首先要知道的是,除了raw文件夹,上述的其它文件夹主要是用来适配不同屏幕的显示密度的,放在不同文件夹里等于是告诉系统,我这张图片是针对哪一种显示密度的设备,如果图片放置的文件夹与实际运行的设备密度不一致,那么系统会对这张图片进行放大或缩小。比如:我把图片放置在xhdpi(dpi是320)里面,但是我实际运行的设备是640,xxxhdpi里又没有放置任何图片,那么这个时候系统就会对放置在xhdpi里的同名图片进行缩放。

在屏幕dpi为160时,1dp = 1px,也就是说如果运行设备的屏幕的dpi是160时,图片是可以1:1正常显示的,查看当前屏幕的dpi和density可以通过下列API:
float density = getResources().getDisplayMetrics().density;
int densityDpi = getResources().getDisplayMetrics().densityDpi;
通过测试,我手机的dpi为640,density是4,也就是说当我把图片放在xxxhdpi里时,图片可以正常匹配,系统不会做任何处理,所以上面放在xxxhdpi时,运行的Log是正确的,刚好是1920*1080,那放置到其它的文件夹里的尺寸是如何计算的呢?个人猜测应该是这样:当放置在
drawable-mdpi时,该文件夹对应的dpi是160,density是1,实际屏幕dpi是640,密度是4,不符合要求,放大4倍 ,(7680*4320);
drawable-hdpi时,该文件夹对应的dpi是240,density是1.5,实际屏幕dpi是640,密度是4,不符合要求,放大2.666 (4/1.5) 倍, (5120*2880);
drawable-xhdpi时,该文件夹对应的dpi是320,density是2,实际屏幕dpi是640,密度是4,不符合要求,放大2 (4/2) 倍, (3840*2160);
drawable-xxhdpi时,该文件夹对应的dpi是480,density是3,实际屏幕dpi是640,密度是4,不符合要求,放大1.333 (4/3) 倍, (2560*1440);
drawable-xxxhdpi时,该文件夹对应的dpi是640,density是4,实际屏幕dpi是640,密度是4,符合要求,正常显示, (1920*1080);
因此导致了使用BitmapFactory在decode图片时发生了上述的差异,那么是否有什么途径可以保证decode图片时,得到的图片尺寸与实际的图片尺寸相一致呢?这里有两种方法:
第一种方法,如果仅仅是为了获取图片的尺寸,不需要获取其对应的Bitmap,可以通过下列方式:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img_mac_os_x, options);
Log.i("xp.chen", "decode bitmap width: "+options.outWidth+", bitmap height: "+options.outHeight);
这里通过 options.outWidth 和 options.outHeight 拿到的就是图片实际的宽高,经测试刚好是1920*1080,注意这里返回的bitmap对象是NULL。
第二种方法,不仅仅是为了要拿到图片的尺寸,也需要拿到对应的Bitmap,可以通过下列方式:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img_mac_os_x, options);
if (bitmap != null) {
Log.i("xp.chen", "decode bitmap width: "+bitmap.getWidth()+", bitmap height: "+bitmap.getHeight());
}
设置 options.inScaled 为false,等于告诉系统,不要对该图片进行缩放,通过这种方法拿到的宽高也是1920*1080。
BitmapFactory: 通过Bitmap的getWidth和getHeight方法获取到的尺寸与实际尺寸不符的问题的更多相关文章
- Bitmap通过getWidth和getHeight获取尺寸不符
在使用BitmapFactory载入图片时,常会出现这样的情况,返回的图片尺寸与实际尺寸不符.这是因为我们把图片资源放到res/drawable文件路径下时,选择的文件不同所致.不同的目录会有不同的缩 ...
- Bitmap通过getWidth和getHeight获取尺寸不符 -- 误以为是Matrix失效(哈)
参考:Bitmap通过getWidth和getHeight获取尺寸不符 因为项目需要我想做个这样的地图出来 这个图的的分辨率是1190 * 666的 在地图上定位,我底图是固定分辨率的,那么算个坐标就 ...
- Android中 Bitmap和Drawable相互转换的方法
1.Drawable->Bitmap Resources res=getResources(); Bitmap bmp=BitmapFactory.decodeResource(res, R.d ...
- c#图像处理入门(-bitmap类和图像像素值获取方法)
c#图像处理入门 -bitmap类和图像像素值获取方法 一.Bitmap类 Bitmap对象封装了GDI+中的一个位图,此位图由图形图像及其属性的像素数据组成.因此Bitmap是用于处理由像素数据定义 ...
- BitmapFactory.decodeStream(inputStream)返回null的解决方法
场景:Android,通过inputStream从网络上获取图片 随后两次使用BitmapFactory对InputStream进行操作,一次获取宽高,另一次缩放 但是在缩放时,发现inputStre ...
- Android开发 获取View的尺寸的2个方法
前言 总所周知,在activity启动的onCreate或者其他生命周期里去获取View的尺寸是错误的,因为很有可能View并没有初始化测量绘制完成.你这个时候获取的宽或的高不出意外就是0.所以,我们 ...
- python学习历程之split()方法获取cmd mysql 结果集
if __name__=='__main__': FServerId = raw_input("Please input source id:") GetFileKey(FServ ...
- [Android Pro] 关于inputStream.available()方法获取文件的总大小
reference to :http://hold-on.iteye.com/blog/1017449 如果用inputStream对象的available()方法获取流中可读取的数据大小,通常我们调 ...
- 使用jquery中height()方法获取各种高度大全
alert($(window).height()); //浏览器当前窗口可视区域高度 alert($(document).height()); //浏览器当前窗口文档的高度 alert($(docum ...
随机推荐
- django内置缓存
由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,5 ...
- Java关键字—final
final—不可变的,用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变. 修饰范围: 1.修饰类,被final关键字修饰的类无法被继承: 2.修饰方法,被f ...
- 【搜索/tarjan找环】zznu-简单环路
简单环路 题目描述 有一个N x M 大小的地图,地图中的每个单元包含一个大写字母. 若两个相邻的(这里的相邻指“上下左右”相邻)点上的字母相同,我们可以用线段连接这两个点. 若存在一个包含同一字母的 ...
- webpack4 打包优化
1 参考文章 彻底解决 webpack 打包文件体积过大 webpack4提升180%编译速度 详解webpack4之splitchunksPlugin代码包分拆 webpack v4 中的断舍离 开 ...
- java中byte的范围计算
概念:java中用补码表示二进制数,补码的最高位是符号位,最高位为“0”表示正数,最高位为“1”表示负数.正数补码为其本身:负数补码为其绝对值各位取反加1:例如:+21,其二进制表示形式是000101 ...
- 多任务案例--文件夹copy.py
import os import multiprocessing def copy_file(q,file_name,new_folder_name,old_folder_name): with op ...
- python - redis 的使用
1.redis连接 redis提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令,Redis是StrictRe ...
- BZOJ 3698: XWW的难题(有源汇上下界最大流)
题面 XWW是个影响力很大的人,他有很多的追随者.这些追随者都想要加入XWW教成为XWW的教徒.但是这并不容易,需要通过XWW的考核. XWW给你出了这么一个难题:XWW给你一个N*N的正实数矩阵A, ...
- sql server 常见约束
1.not null 非空约束 ①强制列不接受空值 ②例:创建表时,name varchar(6) not null, 2.unique 唯一性约束 ①约束唯一标识数据库表中的每条记录 ②unique ...
- 后台(一)vue+element-ui (按需加载)
vue init webpack 项目名称 npm install axios //先安装! npm install --save axios vue-ax ...