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 ...
随机推荐
- Redis for C#
ServiceStack.Redis 初识Redis时接触到的.Net-Redis组件是 ServiceStack.Redis,其V3系列的最新版本是:ServiceStack.Redis.3.9.2 ...
- Oracle存储过程、函数、包加密wrap
wrap加密可以将PL/SQL的代码实现部分隐藏,提高代码的安全性,如存储过程.函数.包等都隐藏. wrap加密的方法有两种,下面以函数为例分别介绍一下: 方法一: 编写好函数后保存到 d:\test ...
- python实现查找算法
搜索是在一个项目集合中找到一个特定项目的算法过程.搜索通常的答案是真的或假的,因为该项目是否存在. 搜索的几种常见方法:顺序查找.二分法查找.二叉树查找.哈希查找 线性查找线性查找就是从头找到尾,直到 ...
- P1078 文化之旅[最短路]
题目背景 本题是错题,后来被证明没有靠谱的多项式复杂度的做法.测试数据非常的水,各种玄学做法都可以通过(比如反着扫),不代表算法正确.因此本题题目和数据仅供参考. 题目描述 有一位使者要游历各国,他每 ...
- postgresql —— 零碎笔记
聚合函数 -- 聚合查询 SELECT city, max(temp_lo) FROM weather WHERE city LIKE 'S%' GROUP BY city HAVING max(te ...
- MessageDigest的功能及用法
MessageDigest 类为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法.信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值. MessageDigest ...
- 把hdfs数据写入到hbase表
功能:把hdfs上的数据写入到hbase表. hadoop的mapreduce输出要导入到hbase表,最好先输出HFile格式,再导入hbase,因为HFile是hbase的内部存储格式,所以导入效 ...
- Elasticsearch 调优之 shrink
对于索引分片数量,我们一般在模板中统一定义,在数据规模比较大的集群中,索引分片数一般也大一些,在我的集群中设置为 24.但是,并不是所有的索引数据量都很大,这些小数据量的索引也同样有较大的分片数.在 ...
- 窗口看门狗 WWDG
一,窗口看门狗 二,喂狗注意事项 三,程序设计 1.检查复位状态,有助于观察当前工作的可靠性 /* Check if the system has resumed from WWDG reset ,检 ...
- AtCoder Beginner Contest 133
目录 Contest Info Solutions A. T or T B.Good Distance C. Remainder Minimization 2019 D. Rain Flows int ...