问题

今天无意中发现了一个问题,通过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方法获取到的尺寸与实际尺寸不符的问题的更多相关文章

  1. Bitmap通过getWidth和getHeight获取尺寸不符

    在使用BitmapFactory载入图片时,常会出现这样的情况,返回的图片尺寸与实际尺寸不符.这是因为我们把图片资源放到res/drawable文件路径下时,选择的文件不同所致.不同的目录会有不同的缩 ...

  2. Bitmap通过getWidth和getHeight获取尺寸不符 -- 误以为是Matrix失效(哈)

    参考:Bitmap通过getWidth和getHeight获取尺寸不符 因为项目需要我想做个这样的地图出来 这个图的的分辨率是1190 * 666的 在地图上定位,我底图是固定分辨率的,那么算个坐标就 ...

  3. Android中 Bitmap和Drawable相互转换的方法

    1.Drawable->Bitmap Resources res=getResources(); Bitmap bmp=BitmapFactory.decodeResource(res, R.d ...

  4. c#图像处理入门(-bitmap类和图像像素值获取方法)

    c#图像处理入门 -bitmap类和图像像素值获取方法 一.Bitmap类 Bitmap对象封装了GDI+中的一个位图,此位图由图形图像及其属性的像素数据组成.因此Bitmap是用于处理由像素数据定义 ...

  5. BitmapFactory.decodeStream(inputStream)返回null的解决方法

    场景:Android,通过inputStream从网络上获取图片 随后两次使用BitmapFactory对InputStream进行操作,一次获取宽高,另一次缩放 但是在缩放时,发现inputStre ...

  6. Android开发 获取View的尺寸的2个方法

    前言 总所周知,在activity启动的onCreate或者其他生命周期里去获取View的尺寸是错误的,因为很有可能View并没有初始化测量绘制完成.你这个时候获取的宽或的高不出意外就是0.所以,我们 ...

  7. python学习历程之split()方法获取cmd mysql 结果集

    if __name__=='__main__': FServerId = raw_input("Please input source id:") GetFileKey(FServ ...

  8. [Android Pro] 关于inputStream.available()方法获取文件的总大小

    reference to :http://hold-on.iteye.com/blog/1017449 如果用inputStream对象的available()方法获取流中可读取的数据大小,通常我们调 ...

  9. 使用jquery中height()方法获取各种高度大全

    alert($(window).height()); //浏览器当前窗口可视区域高度 alert($(document).height()); //浏览器当前窗口文档的高度 alert($(docum ...

随机推荐

  1. JAVA笔记整理(四),JAVA中的封装

    什么是封装 所谓的封装就是把数据项和方法作为一个独立的整体隐藏在对象的内部,具体的实施细节不对外提现,仅仅保留有限的外部接口,封装外的用户只能通过接口来进行操作.就好比开启一台电脑需要进行很多个步骤, ...

  2. 华为SDN:解决传统网络3大问题

    转:http://mp.ofweek.com/tele/a145613326756 科技潮人 2013-08-05 14:20 传统网络之困 互联网爆炸式增长,除了规模和发展速度远超之前所有曾出现的数 ...

  3. 关于Django auth注册登录模块的具体使用

    from django.urls import path from . import views urlpatterns = [ #主页,用来显示类别等其他数据 path('',views.index ...

  4. C++——多态实现原理分析

    前言 虚函数执行速度要稍慢一些.为了实现多态性,每一个派生类中均要保存相应虚函数的入口地址表,函数的调用机制也是间接实现.所以多态性总是要付出一定代价,但通用性是一个更高的目标. 实验环境 Windo ...

  5. kubbernetes Flannel网络部署(五)

    一.Flannel生成证书 1.创建Flannel生成证书的文件 [root@linux-node1 ~]# vim flanneld-csr.json { "CN": " ...

  6. P2280 [HNOI2003]激光炸弹[前缀和]

    题目描述 输入输出格式 输入格式: 输入文件名为input.txt 输入文件的第一行为正整数n和正整数R,接下来的n行每行有3个正整数,分别表示 xi,yi ,vi . 输出格式: 输出文件名为out ...

  7. <c:set> 标签

    <c:set> 标签 JSP 标准标签库 <c:set>标签用于设置变量值和对象属性. <c:set>标签就是<jsp:setProperty>行为标签 ...

  8. BZOJ1257: [CQOI2007]余数之和——整除分块

    题意 求 $\sum _{i=1}^n k \ mod \ i$($1\leq n,k\leq 10^9$). 分析 数据范围这么大 $O(n)$ 的复杂度也挺不住啊 根据取模的意义,$k \ mod ...

  9. windows nginx 搭建文件服务器(通俗易懂)

    在一些项目里面,有时候需要访问图片的时候.相信很多人都是的直接把文件放到项目里面的: 今天在这里给大家介绍的是利用nginx 搭建图片服务器,直接访问磁盘上的图片. 方法一(使用root关键字): l ...

  10. sql server join ,inner join ,left join ,right join 的使用

    测试数据脚本 CREATE TABLE Atable ( S# INT, Sname nvarchar(32), Sage INT, Sfrom nvarchar(8) ) insert into A ...