为什么会用到这个类?
当我们想将一张图片转换成为bitmap的时候我们就需要用到BitMapFactory方法
当我们想对bimap进行一些调整的时候,需要用到 Bitmap.createBitmap方式来进行调整
关于Bitmap加载,我们离不开类BitmapFactory。
加载文件系统图:BitmapFactory.decodeFile(url)
加载本地资源图:BitmapFactory.decodeResource(resources,R.drawable.**)
加载输入流:BitmapFactory.decodeStream()
加载字节组:BitmapFactory.decodeByteArray()
当加载到比较大的图的时候,会导致内存溢出,这个时候就需要用到Options这个类对图片进行一个压缩处理。实现图片的高效加载。
BitMapFactory.Options:
- inJustDecodeBounds: 设置为true,则在解码的时候不会返回bitmap,只会返回这个bitmap的尺寸。目的:在只想得到view的尺寸而不需要加载到内存中。
- 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。
- inPreferredConfig:设置色彩模式,默认为ARGB_8888,在这个模式一个像素4bytes空间。对透明度不做要求的话用RGB_565一个像素2bytes。
- inPremultiplied:这个值和透明度通道到有关,默认为true(返回的bitmap的颜色通道上会预先附加上透明度通道)。
- inDither:默认为false(不采用抖动解码)
- inDensity:表示这个bitmap的像素密度(对应的是DisplayMetrix中的densityDpi 不是density)。
- inTargetDensity:表示要被画出来的目标 像素密度(对应的是DisplayMetrix中的densityDpi 不是density)。
- inScreenDensity:表示实际设备的像素密度(对应的是DisplayMetrix中的densityDpi 不是density)。
- inScaled:设置这个bitmap是否可以被缩放。默认为true可以被缩放。
- inPreferQualityOverSpeed:这个值表示是否在解码时图片有更高的品质,仅用于JPEG格式。如果设置为true,则图片会有更高的品质,但是会解码速度会很慢。
- outWidth和outHeigh:表示这个Bitmap的宽和高,一般和inJustDecodeBounds一起使用来获得Bitmap的宽高,但是不加载到内存。
压缩方式一:
- 尺寸压缩:压缩图片的像素【一张图片所占内存大小 = 图片类型(ALPHA_8/ARGB_4444/ARGB_8888/RGB_256) * 宽 * 高】
图片类型:也就是色彩模式
- ALPHA_8:每个像素占用1byte内存。
- ARGB_4444:每个像素占用2byte内存
- ARGB_8888:每个像素占用4byte内存
- RGB_565:每个像素占用2byte内存
而android默认的色彩模式就是ARGB_8888,质量最高,同时内存也是最大。效果也肯定是最好的。假设一张图1024 1024 模式ARGB_8888 则内存:1024 * 1024 * 4 = 4M
修改图片类型:optins.inPreferredConfig
用这个改变内存大小的三个值得第一个。图片类型,指定为更小的色彩模式,可以让图片的内存变小。
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig= Bitmap.Config.RGB_565;
修改图片采样率:optins.inSampleSize
options.inPreferredConfig=2;
- 当inSampleSize=1时,采样后的图片为图片的原始大小。
- 除了1以外,inSampleSize的取值应该总为2的整数倍,否则会【向下取整】,取一个最接近2的整数倍,比如inSampleSize=3时,系统会取inSampleSize=2
- 当inSampleSize=2时,采样后的图片的宽高均为原始图片宽高的1/2
假设一张10241024,模式为ARGB_8888的图片,inSampleSize=2,原始占用内存大小是4MB,采样后的图片占用内存大小就是(1024/2) * (1024/2 ) 4 = 1MB
文章引用:
作者:芒果味的你呀
链接:https://www.jianshu.com/p/c77158b6e07e
来源:简书
来自个人使用分析
inDensity 和 inTargetDensity他两一般都是搭配使用的。
在官方解释isDensity里面有这么一句话:
In addition,
* if {@link #inScaled} is set (which it is by default} and this
* density does not match {@link #inTargetDensity}, then the bitmap
* will be scaled to the target density before being returned.
讲的是当设置了isDensity 和 inTargetDensity的时候 如果二者不相等,那么会根据inTargetDensity的值自动进行一个缩放。
例子:
/**
* 设 width = 240 bg:宽480 高:480
* 则:options.inDensity = options.outWidth //480
* options.inTargetDensity = widt //240
* 由于inDensity 和 inTargetDensity 的值不相等 那么我们得到的bitmap的宽度会等于 240 高于也会变成240
* 自动实现了缩放效果。
**/
private fun getAvatar(width: Int, bg: Int): Bitmap {
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
BitmapFactory.decodeResource(resources, bg, options)
options.inJustDecodeBounds = false
options.inDensity = options.outWidth
options.inTargetDensity = width
return BitmapFactory.decodeResource(resources, bg, options)
}
网友评论