Bitmap的内存管理优化与长图加载

APP的优化是任重而道远的过程,必须在意每一个环节,否者当你想要优化的时候,发现到处都是坑,已经不知道填补哪里了,所以我们必须一点一滴的做起。

Bitmap

Bitmap的内存管理优化

大量Bitmap的创建和垃圾回收,会产生内存抖动,引发卡顿。一次性加载超大的图片会导致OOM,所以我们要避免或者合理的使用循环缩放,压缩,缩放的目的主要是合理的使用(避免大图加载OOM,因为手机实际是用不到那么大的图片的)。或者使用一些比较好的第三方工具如Glide。不要怀疑bitmap的优化就是这么一句。)

Bitmap相关方法总结

public void recycle() // 回收位图占用的内存空间,把位图标记为Dead

public final boolean isRecycled() //判断位图内存是否已释放

public final int getWidth() //获取位图的宽度

public final int getHeight() //获取位图的高度

public final boolean isMutable() //图片是否可修改

public int getScaledWidth(Canvas canvas) //获取指定密度转换后的图像的宽度

public int getScaledHeight(Canvas canvas) //获取指定密度转换后的图像的高度

public boolean compress(CompressFormat format, int quality, OutputStreamstream) //按指定的图片格式以及画质,将图片转换为输出流

public static Bitmap createBitmap(Bitmap src) //以 src 为原图生成不可变得新图像

public static Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter) //以 src 为原图,创建新的图像,指定新图像的高宽以及是否可变。

public static Bitmap createBitmap(int width, int height, Config config) //创建指定格式、大小的位图

public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height) //以 source 为原图,创建新的图片,指定起始坐标以及新图像的高宽。


BitmapFactory工厂类

Option 参数类

public boolean inJustDecodeBounds

//如果设置为 true ,不获取图片,不分配内存,但会返回图片的高度宽度信息。如果将这个值置为 true ,那么在解码的时候将不会返回 bitmap ,只会返回这个 bitmap 的尺寸。这个属性的目的是,如果你只想知道一个 bitmap 的尺寸,但又不想将其加载到内存时。这是一个非常有用的属性。

public int 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。

public int outWidth //获取图片的宽度值

public int outHeight //获取图片的高度值 ,表示这个 Bitmap 的宽和高,一般和

inJustDecodeBounds 一起使用来获得 Bitmap 的宽高,但是不加载到内存。

public int inDensity //用于位图的像素压缩比

public int inTargetDensity //用于目标位图的像素压缩比(要生成的位图)

public byte[] inTempStorage //创建临时文件,将图片存储

public boolean inScaled //设置为 true 时进行图片压缩,从 inDensity 到inTargetDensity

public boolean inDither //如果为 true ,解码器尝试抖动解码

public Bitmap.Config inPreferredConfig //设置解码器,这个值是设置色彩模式,默认值是 ARGB_8888 ,在这个模式下,一个像素点占用4bytes空间,一般对透明度不做要求的话,一般采用 RGB_565 模式,这个模式下一个像素点占用2bytes。

public String outMimeType //设置解码图像

public boolean inPurgeable //当存储 Pixel 的内存空间在系统内存不足时是否可以被回收

public boolean inInputShareable // inPurgeable 为 true 情况下才生效,是否可以共享一个 InputStream

public boolean inPreferQualityOverSpeed //为 true 则优先保证 Bitmap 质量其次是解码速度

public boolean inMutable //配置 Bitmap 是否可以更改,比如:在 Bitmap 上隔几个像素加一条线段

public int inScreenDensity//当前屏幕的像素密度

工厂方法

public static Bitmap decodeFile(String pathName, Options opts) //从文件读取图片

public static Bitmap decodeFile(String pathName)

public static Bitmap decodeStream(InputStream is) //从输入流读取图片

public static Bitmap decodeStream(InputStream is, Rect outPadding, Optionsopts)

public static Bitmap decodeResource(Resources res, int id) //从资源文件读取图片

public static Bitmap decodeResource(Resources res, int id, Options opts)

public static Bitmap decodeByteArray(byte[] data, int offset, int length) //从数组读取图片

public static Bitmap decodeByteArray(byte[] data, int offset, int length,Options opts)

public static Bitmap decodeFileDescriptor(FileDescriptor fd) //从文件读取文件 与decodeFile 不同的是这个直接调用JNI函数进行读取 效率比较高

public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding,Options opts)


单个像素的字节大小

单个像素的字节大小由Bitmap的一个可配置的参数Config来决定。

Bitmap中,存在一个枚举类Config,定义了Android中支持的Bitmap配置:


显而易见,在能够接受的情况下RGB_565内存更小

Bitmap加载方式

Bitmap 的加载方式有 Resource 资源加载、本地(SDcard)加载、网络加载等加载方式。(详细不细说)

Bitmap的内存回收

使用Bitmap.recycle()方法进行Bitmap的内存回收。

drawable图片加载放置

图片放在某个特定drawable中,比如drawable-hdpi,如果设备的屏幕密度高于当前drawable目录所代表的密度,则图片会被放大,否则会被缩小放大或缩小比例 = 设备屏幕密度 / drawable目录所代表的屏幕密度。

Bitmap长图加载

思路,通过获取需要加载的部分高宽:使用decodeRegion区域加载,使用BigmapRegionDecoder流方式加载,对图像进行部分加载。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容