Bitmap 完全掌握

本文详细探讨了Android中Bitmap的内存管理,包括像素数据的储存位置,2.3及更高版本的变化,以及如何避免内存浪费。Bitmap的复用策略如缓存和inBitmap的使用被提及,同时讲解了如何计算Bitmap的内存占用。此外,文章还介绍了inSampleSize和compress的使用,以及inDensity和inTargetDensity在实现任意等比缩放中的作用。
摘要由CSDN通过智能技术生成

记录一下以前看到过的知识点。

Bitmap 像素数据的储存位置

先看官方文档

在Android Android 2.2(API级别8)及更低版本上,当 GC 发生时,应用程序的线程会停止。这会导致延迟,从而降低性能。 Android 2.3添加了并发GC,这意味着在位图不再被引用后很快就会被回收。

2.3之前的像素存储需要的内存是在native上分配的,并且生命周期不太可控,可能需要用户自己回收。 2.3-7.1之间,Bitmap的像素存储在Dalvik的Java堆上,而8.0之后的像素内存又重新回到native上去分配,不需要用户主动回收,8.0之后图像资源的管理更加优秀,极大降低了OOM。

假设我们有这样的一个手机,它的 system/build.prop 配置如下:

// 表示应用程序启动后为其分配的初始大小为8m
dalvik.vm.heapstartsize=8m

// 每个应用程序最大内存可分配到64m
dalvik.vm.heapgrowthlimit=192m

// 单个虚拟机可分配的最大内存256m
// 使用大堆时,极限堆大小。一旦dalvik heap size超过这个值,直接引发oom。
// 在android开发中,如果要使用大堆,需要在manifest中指定android:largeHeap为true。这样dvm heap最大可达dalvik.vm.heapsize。
dalvik.vm.heapsize=512m

//  设定内存利用率的百分比,当实际的利用率偏离这个百分比的时候,虚拟机会在GC的时候调整堆内存大小,让实际占用率向个百分比靠拢。
dalvik.vm.heaptargetutilization=0.75

dalvik.vm.heapminfree=512k

dalvik.vm.heapmaxfree=8m

我们不断的解析图片并持有所有图片的引用:

void test{
   
	Map<String, Bitmap> map = new HashMap<>();
	for(int i=0 ; i<10;i++) {
   
		Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.green);
		map.put("" + Syste
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
windows平台上支持BITMAPCOREHEADER、BITMAPINFOHEADER、BITMAPV4HEADER、BITMAPV5HEADER四种类型位图的类库! 简单用法举例: DibBitmap bmp,ret,tmp; bmp.Open(_T("E:\\bmp.bmp"));//打开 bmp.ConvertBit(4,ret);//转为4位位图,ret保存返回值 ret.RotateLeft(tmp);//向左旋转90度,tmp保存返回值 tmp.Invert();//所有像素反色,即RGB(1,2,3)变为RGB(254,253,252) tmp.At(10,10)=tmp.At(20,20);//单个像素点的取值和赋值操作 tmp.At(10,20)=ret.At(30,30);//注意,设置成的颜色如果颜色表内不存在,会设置成相近色 tmp.At(20,10)=RGB(255,0,0); bmp.AlphaBlend(0,0,tmp,128,RGB(255,255,255),true);//tmp以透明度128画到bmp的(0,0)处,其中tmp中的白色会镂空 bmp.Mirror();//bmp水平翻转 bmp.ConvertBit(16,ret,true);//转为5-6-5型16位位图,ret保存返回值 ret.SetClipbrd();//存入剪切板中 ret.Save(_T("E:\\bmp2.bmp"));//保存到文件 该类的头文件接口大致如下: class DibBitmap { BITMAPFILEHEADER* m_pbmfh; DWORD m_size;//保存m_pbmfh中malloc出来的内存大小,即是capacity//不为0时保证图像是可以处理的 public: enum BmType{NONE=0,CORETYPE,INFOTYPE,V4TYPE,V5TYPE}; public: class reference { //略.. }; public://DibBitmap01.cpp DibBitmap(); explicit DibBitmap(LPCTSTR pstrFileName); explicit DibBitmap(BITMAPFILEHEADER* pbmfh);//只是简单的赋值给成员变量m_pbmfh DibBitmap(HDC hdc, HBITMAP hBitmap, int BitCount);//1,4,8;16,24,32 DibBitmap(const DibBitmap& rhs); ~DibBitmap(); bool Open(LPCTSTR pstrFileName);//打开失败会Close() bool Save(LPCTSTR pstrFileName)const; void Close(); void Swap(DibBitmap& rhs); DibBitmap& operator=(const DibBitmap& rhs);//不一定申请过新内存 public://DibBitmap01.cpp BITMAPFILEHEADER* Get();//获取文件头 const BITMAPFILEHEADER* Get()const; BITMAPINFOHEADER* GetInfoHead();//获取信息头 const BITMAPINFOHEADER* GetInfoHead()const; RGBQUAD* GetQuad();//获取颜色表//没有颜色表,则返回NULL const RGBQUAD* GetQuad()const; BYTE* GetByte();//获取图素位 const BYTE* GetByte()const; bool GetMask(DWORD* dwMask,bool b565=false)const; //dwMask个数为四,需要屏蔽码时,依次存入RGB屏蔽码,并返回true //当为BITMAPV4HEADER以上时,还存入AlphaMask;b565参数同GetClr bool Attach(BITMAPFILEHEADER* pbmfh); BITMAPFILEHEADER* Detach();//返回值最后须free掉 HBITMAP CreateBitmap(HDC hdc)const;//返回值最后须DeleteObject掉 HBITMAP CreateDibSection ()const;//返回值最后须DeleteObject掉 BmType Type()const; DWORD Capacity()const;//返回m_size的值//注意,此值可能小于实际malloc的内存长度 DWORD FileSize()const;//整个文件的大小//不是返回m_size的值,m_size的值大于等于此返回值 DWORD BitsSize()const;//图素位的大小,即去掉文件头,信息头和颜色表之后的大小 DWORD Offset()const;//图素位的偏移量 LONG Width()const; LONG Height()const;//可能为负值 WORD Planes()const; WORD BitCount()const; DWORD ClrUsed()const; //一般是4,8位图才小于2^(4,8),其余的等于对应颜色数,m_pbmfh为空时返回0,32位图时,返回-1,16位555位图颜色数按565算 public://DibBitmap02.cpp LPTSTR DisplayDibHeader (LPTSTR szBuffer)const;//szBuffer得大于1200个//返回szBuffer RGBQUAD GetClr(size_t x,size_t y,bool b565=false)const; //获取(x,y)处的颜色值,已考虑方向问题,b565只有在16位深位图且没有屏蔽码时才有用,指明是5-5-5还是5-6-5 COLORREF GetRGBClr(size_t x,size_t y,bool b565=false)const;//条件同上//返回的最高位为0 bool GetClipbrd(HWND hwnd);//失败不一定会Close() void SetClipbrd(HWND hwnd)const; //If hwnd is NULL, the open clipboard is associated with the current task. void Mirror(bool bHoriz);//镜像//false表示垂直镜像 public://DibBitmap03.cpp void Invert(bool b565=false);//反色//在这里b565参数不起任何作用 RGBQUAD Invert(size_t x,size_t y,bool b565=false);//(x,y)处的颜色反色,返回反色后的近似颜色 RGBQUAD SetClr(size_t x,size_t y,RGBQUAD quad,bool b565=false);//设置颜色,返回设置成的最相近的颜色 COLORREF SetRGBClr(size_t x,size_t y,COLORREF clr,bool b565=false);//设置颜色,返回设置成的最相近的颜色 //以下两个函数相当牛逼,可直接引用修改颜色 COLORREF At(size_t x,size_t y,bool b565=false)const;//获取(x,y)处的颜色 reference At(size_t x,size_t y,bool b565=false);//获取(x,y)处的颜色引用,可直接进行修改 void AlphaBlend(int x,int y,const DibBitmap& rhs,BYTE bAlpha,COLORREF clr,bool bClr=false,bool b565=false); //把rhs以透明度bAlpha画到this中的(x,y)处(可以为负),注意:当&rhs==this时直接返回,啥也不操作 //若bClr为true,则clr参数有用,rhs中颜色值为clr的像素点完全透明 void RotateLeft(DibBitmap& ret)const; //this旋转(逆时针90度)后存入ret中,若this原先为空,则不改变ret,注意:当&ret==this时直接返回,啥也不操作 void RotateRight(DibBitmap& ret)const; //this旋转(顺时针90度)后存入ret中,若this原先为空,则不改变ret,注意:当&ret==this时直接返回,啥也不操作 void RotateOpposite();//旋转180度,注意后面没有const,此函数是旋转自身 public://DibBitmap04.cpp bool ConvertBit(WORD BitCount,DibBitmap& ret,bool b565=false)const; //转为同类型的不同位数位图//1,4,8;16,24,32,注意:当&ret==this时直接返回,啥也不操作 }; 说明: 此类支持四种位图格式: BITMAPCOREHEADER、BITMAPINFOHEADER、BITMAPV4HEADER、BITMAPV5HEADER。 该类像素点坐标序号从0开始,原点位于位图左上角,不管位图信息头的高度字段是否为负,内部都已作转化处理 暂不支持这四种位图的以下几种情况: 1、biCompression字段为BI_RLE4,BI_RLE8,BI_JPEG,BI_PNG的位图; 2、BITMAPV5HEADER时,bV5CSType字段等于PROFILE_LINKED或PROFILE_EMBEDDED时的位图。 有问题联系:hastings1986@163.com
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值