• 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  "+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 7680, bitmap height: 4320

    drawable-mdpi:I/xp.chen: decode bitmap 7680, bitmap height: 4320

    drawable-hdpi:I/xp.chen: decode bitmap 5120, bitmap height: 2880

    drawable-xhdpi:I/xp.chen: decode bitmap 3840, bitmap height: 2160

    drawable-xxhdpi:I/xp.chen: decode bitmap 2560, bitmap height: 1440

    drawable-xxxhdp:I/xp.chen: decode bitmap 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  "+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  "+bitmap.getWidth()+", bitmap height: "+bitmap.getHeight());
    }

    设置 options.inScaled 为false,等于告诉系统,不要对该图片进行缩放,通过这种方法拿到的宽高也是1920*1080。

  • 相关阅读:
    年报统计系统—基本信息模块的目标文档
    用户分析
    第一周第三天
    第一周第二天
    第一周第一天
    学习进度条第三周
    学习进度表第二周
    四则运算2
    构建之法阅读笔记 01
    软件工程概论学习进度表第一周
  • 原文地址:https://www.cnblogs.com/yongdaimi/p/11119509.html
Copyright © 2020-2023  润新知