美文网首页
BitmapFactory.Option 正确使用方式

BitmapFactory.Option 正确使用方式

作者: 不服输的小蜗牛 | 来源:发表于2021-01-26 21:03 被阅读0次

1.BitmapFactory.Option 这个类我想大家都不陌生,项目中有展示本地大图应该都用过,主要是来帮助我们已合适的大小加载bitmap,减小bitmap占内存。

BitmapFactory.Option的属性

属性 描述
inJustDecodeBounds 如果将这个值置为true,那么在解码的时候将不会返回bitmap,只会返回这个bitmap的尺寸。这个属性的目的是,如果你只想知道一个bitmap的尺寸,但又不想将其加载到内存时。这是一个非常有用的属性。
inSampleSize 这个值是一个int,当它小于1的时候,将会被当做1处理,如果大于1,那么就会按照比例(1 / inSampleSize)缩小bitmap的宽和高、降低分辨率,大于1时这个值将会被处置为2的倍数。例如,width=100,height=100,inSampleSize=2,那么就会将bitmap处理为,width=50,height=50,宽高降为1 / 2,像素数降为1 / 4。
outWidth Bitmap的宽,一般和inJustDecodeBounds一起使用来获得Bitmap的宽高,但是不加载到内存。
outHeight Bitmap的高,一般和inJustDecodeBounds一起使用来获得Bitmap的宽高,但是不加载到内存。
inPreferredConfig 这个值是设置色彩模式,默认值是ARGB_8888,在这个模式下,一个像素点占用4bytes空间,一般对透明度不做要求的话,一般采用RGB_565模式,这个模式下一个像素点占用2bytes。
inPremultiplied 这个值和透明度通道有关,默认值是true,如果设置为true,则返回的bitmap的颜色通道上会预先附加上透明度通道
inDither 这个值和抖动解码有关,默认值为false,表示不采用抖动解码
inDensity 表示这个bitmap的像素密度(对应的是DisplayMetrics中的densityDpi,不是density)。
inTargetDensity 表示要被画出来时的目标像素密度(对应的是DisplayMetrics中的densityDpi,不是density)。
inScreenDensity 表示实际设备的像素密度(对应的是DisplayMetrics中的densityDpi,不是density)。
inScaled 设置这个Bitmap是否可以被缩放,默认值是true,表示可以被缩放。
inPreferQualityOverSpeed 这个值表示是否在解码时图片有更高的品质,仅用于JPEG格式。如果设置为true,则图片会有更高的品质,但是会解码速度会很慢。

我们去百度搜索android 加载大图。90%都是通过设置inSampleSize来实现的图片缩放。代码如下

public static int calculateInSampleSize(BitmapFactory.Options options,  
        int reqWidth, int reqHeight) {  
    // 源图片的高度和宽度  
    final int height = options.outHeight;  
    final int width = options.outWidth;  
    int inSampleSize = 1;  
    if (height > reqHeight || width > reqWidth) {  
        // 计算出实际宽高和目标宽高的比率  
        final int heightRatio = Math.round((float) height / (float) reqHeight);  
        final int widthRatio = Math.round((float) width / (float) reqWidth);  
        // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高  
        // 一定都会大于等于目标的宽和高。  
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;  
    }  
    return inSampleSize;  
}  
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,  
        int reqWidth, int reqHeight) {  
    // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小  
    final BitmapFactory.Options options = new BitmapFactory.Options();  
    options.inJustDecodeBounds = true;  
    BitmapFactory.decodeResource(res, resId, options);  
    // 调用上面定义的方法计算inSampleSize值  
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);  
    // 使用获取到的inSampleSize值再次解析图片  
    options.inJustDecodeBounds = false;  
    return BitmapFactory.decodeResource(res, resId, options);  
}  

通过属性介绍我们也知道inSampleSize有许多局限性,比如说只能是2的倍数。
现在我有个需求是,我图片大小是100px.但是我view大小是75px。

1.我能通过设置inSampleSize来把图片大小设置为75px吗?
答案:可以的。
2.inSampleSize值为2的话图片大小一定是50px吗?
答案:不一定
如果图片以50大小加载然后再放大到75px,那样图片会失真,显然效果不是很好。
有没有什么办法能让加载的Bitmap和view宽度或者高度一样呢?,那就需要我们用到另外的两个属性,inDensity和inTargetDensity。代码如下

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
                                                         int reqWidth, int reqHeight) {
        // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
        // 调用上面定义的方法计算inSampleSize值
        if(options.outHeight/reqHeight >options.outWidth/reqWidth){
            options.inDensity = options.outHeight;
            options.inTargetDensity =reqHeight;
        }else{
            options.inDensity = options.outWidth;
            options.inTargetDensity = reqWidth;
        }
        // 使用获取到的inSampleSize值再次解析图片
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }

为什么这个代码就能实现大小刚刚好呢?答案就是下面的公式

输出图片的宽高= 原图片的宽高 / inSampleSize * (inTargetDensity / inDensity)

说明:这个计算仅针对于drawable文件夹的图片来说
而对于一个file或者stream那么inDensity和inTargetDensity是不考虑的!他们默认就是0
这样我们在不修改inSampleSize的情况下 通过设置inTargetDensity 和inDensity来达到加载的bitmap和view的宽或者高一致。

相关文章

  • BitmapFactory.Option 正确使用方式

    1.BitmapFactory.Option 这个类我想大家都不陌生,项目中有展示本地大图应该都用过,主要是来帮助...

  • IDEA 正确使用方式

    IDEA 2021.1 以下版本均可激活; 第一步: 下载最新的 IDEA 2021.1 版本安装包 我们先从 I...

  • UIImagePickerController .mediaTy

    先来看最终效果 在OC中的使用方式 在Swift中的使用方式 错误方式,模仿OC的写法 正确方式 实例 在OC使用...

  • Ubuntu下shell发送post json请求的正确姿势

    正确姿势 错误姿势: 注:请求头使用方式正确 -H 'Content-Type':'application/jso...

  • Imtoken钱包正确使用方式

    最近感悟 有一个伙伴,她看了我所有有关数字货币的文章,她并没有看看就过了,而是真的去尝试了。前几天她发给我信息,说...

  • iOS NSTimer 正确使用方式

    本代码来自 《编写高质量iOS与OS X代码的52个有效方法》。 只列出关键的两个类实现 这么做是为了解决循环引用...

  • github-正确使用方式

    第一次: git clone 远程仓库的地址 git status 查看状态 git add . ...

  • sublime的正确使用方式

    先上一张符合我的审美的效果图。 废话不多说,直接干货吧 插件篇 packetControl 建议进入官网后下载Pa...

  • 刘备正确的使用方式

    不仅仅是出装和打钱速度! 技能的合理使用一样重要! 学会连招,一技能,普攻,二技能,普攻,大招,拼命普攻!一套使用...

  • 线程的正确使用方式

    http://android.jobbole.com/82440/ 进程优先级:Active->Visible->...

网友评论

      本文标题:BitmapFactory.Option 正确使用方式

      本文链接:https://www.haomeiwen.com/subject/rxdnzktx.html