问题

今天无意中发现了一个问题,通过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. 【DRF框架】视图组件

    基于mixins视图类 from rest_framework import mixins # 创建视图 class CreateModelMixin(object) def create(self, ...

  2. 可能是东半球最好的 Curl 学习指南,强烈建议收藏!

    本文首发于:微信公众号「运维之美」,公众号 ID:Hi-Linux. 「运维之美」是一个有情怀.有态度,专注于 Linux 运维相关技术文章分享的公众号.公众号致力于为广大运维工作者分享各类技术文章和 ...

  3. Makefile中 的 phony target,empty target

    phony target Makefile的语法很简单 <target> : <prerequisites> [tab] <commands> 目标.先决条件.命令 ...

  4. apache Directory Studio 简易使用

    apache Directory Studio 简易使用 本文首发:https://www.somata.work/2019/apacheDirectoryStudioSimpleUse.html 以 ...

  5. TIME_WAIT状态全是3306解决办法

    刚吃完晚饭,手机短信一直响个不停,打开一看全是告警信息,立即打开电脑查看,发现很多网页很不稳定  一会能打开,一会打不开 登录服务器查看负载情况,cpu.内存 .磁盘io 负载都不高,查看日志发现ng ...

  6. Vim使用技巧(5) -- 宏的录制与使用

    想象一个场景,我们怎么快速把下面的所有链接都加上双引号?可能你手速快,可以很快的加完,但是如果链接有上万个呢?你如何在十秒以内加完? 这时候就需要用到“宏”(其实除了宏vim还有其它方法加上双引号,这 ...

  7. MySQL远程连接错误解决

    远程连接服务器的MySQL数据库,错误代码是1130,是由于无法给远程连接的用户权限的问题 解决方法: 本机登陆mysql后,将mysql数据库中的user表中的host项,从localhost改为% ...

  8. 24 结合webpack使用vue-router

    启用路由 参考官网:https://router.vuejs.org/zh/installation.html webpack就是一个模块化的工具 安装 cnpm i vue-router -S

  9. matlab(5) : 求得θ值后用模型来预测 / 计算模型的精度

    求得θ值后用模型来预测 / 计算模型的精度  ex2.m部分程序 %% ============== Part 4: Predict and Accuracies ==============% Af ...

  10. machine learning(8) -- classification

    分类预测不能使用linear regression, linear regression算法对于分类预测效果很差,应使用logistic regression算法 Logistic regressti ...