Bitmap详解与Bitmap的内存优化.docx

上传人:b****3 文档编号:4865404 上传时间:2022-12-11 格式:DOCX 页数:19 大小:24.17KB
下载 相关 举报
Bitmap详解与Bitmap的内存优化.docx_第1页
第1页 / 共19页
Bitmap详解与Bitmap的内存优化.docx_第2页
第2页 / 共19页
Bitmap详解与Bitmap的内存优化.docx_第3页
第3页 / 共19页
Bitmap详解与Bitmap的内存优化.docx_第4页
第4页 / 共19页
Bitmap详解与Bitmap的内存优化.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

Bitmap详解与Bitmap的内存优化.docx

《Bitmap详解与Bitmap的内存优化.docx》由会员分享,可在线阅读,更多相关《Bitmap详解与Bitmap的内存优化.docx(19页珍藏版)》请在冰豆网上搜索。

Bitmap详解与Bitmap的内存优化.docx

Bitmap详解与Bitmap的内存优化

Bitmap详解与Bitmap的内存优化

一、Bitmap:

Bitmap是Android系统中的图像处理的最重要类之一。

用它可以获取图像文件信息,进行图像剪切、旋转、缩放等操作,并可以指定格式保存图像文件。

常用方法:

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

+publicfinalbooleanisRecycled() //判断位图内存是否已释放

+publicfinalintgetWidth() //获取位图的宽度

+publicfinalintgetHeight() //获取位图的高度

+publicfinalbooleanisMutable() //图片是否可修改

+publicintgetScaledWidth(Canvascanvas) //获取指定密度转换后的图像的宽度

+publicintgetScaledHeight(Canvascanvas) //获取指定密度转换后的图像的高度

+publicbooleancompress(CompressFormatformat,intquality,OutputStreamstream) //按指定的图片格式以及画质,将图片转换为输出流。

format:

压缩图像的格式,如Bitmap.CompressFormat.PNG或Bitmap.CompressFormat.JPEG

quality:

画质,0-100.0表示最低画质压缩,100以最高画质压缩。

对于PNG等无损格式的图片,会忽略此项设置。

stream:

OutputStream中写入压缩数据。

return:

是否成功压缩到指定的流。

+publicstaticBitmapcreateBitmap(Bitmapsrc) //以src为原图生成不可变得新图像

+publicstaticBitmapcreateScaledBitmap(Bitmapsrc,intdstWidth,intdstHeight,booleanfilter) //以src为原图,创建新的图像,指定新图像的高宽以及是否可变。

+publicstaticBitmapcreateBitmap(intwidth,intheight,Configconfig) //创建指定格式、大小的位图

+publicstaticBitmapcreateBitmap(Bitmapsource,intx,inty,intwidth,intheight) //以source为原图,创建新的图片,指定起始坐标以及新图像的高宽。

二、BitmapFactory工厂类:

Option参数类:

+publicbooleaninJustDecodeBounds //如果设置为true,不获取图片,不分配内存,但会返回图片的高度宽度信息。

如果将这个值置为true,那么在解码的时候将不会返回bitmap,只会返回这个bitmap的尺寸。

这个属性的目的是,如果你只想知道一个bitmap的尺寸,但又不想将其加载到内存时。

这是一个非常有用的属性。

+publicintinSampleSize //图片缩放的倍数

这个值是一个int,当它小于1的时候,将会被当做1处理,如果大于1,那么就会按照比例(1/inSampleSize)缩小bitmap的宽和高、降低分辨率,大于1时这个值将会被处置为2的倍数。

例如,width=100,height=100,inSampleSize=2,那么就会将bitmap处理为,width=50,height=50,宽高降为1/2,像素数降为1/4。

+publicintoutWidth //获取图片的宽度值

+publicintoutHeight //获取图片的高度值

表示这个Bitmap的宽和高,一般和inJustDecodeBounds一起使用来获得Bitmap的宽高,但是不加载到内存。

+publicintinDensity //用于位图的像素压缩比

+publicintinTargetDensity //用于目标位图的像素压缩比(要生成的位图)

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

+publicbooleaninScaled //设置为true时进行图片压缩,从inDensity到inTargetDensity

+publicbooleaninDither //如果为true,解码器尝试抖动解码

+publicBitmap.ConfiginPreferredConfig //设置解码器

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

+publicStringoutMimeType //设置解码图像

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

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

+publicbooleaninPreferQualityOverSpeed //为true则优先保证Bitmap质量其次是解码速度

+publicbooleaninMutable //配置Bitmap是否可以更改,比如:

在Bitmap上隔几个像素加一条线段

+publicintinScreenDensity //当前屏幕的像素密度

工厂方法:

+publicstaticBitmapdecodeFile(StringpathName,Optionsopts) //从文件读取图片

+publicstaticBitmapdecodeFile(StringpathName)

+publicstaticBitmapdecodeStream(InputStreamis) //从输入流读取图片

+publicstaticBitmapdecodeStream(InputStreamis,RectoutPadding,Optionsopts)

+publicstaticBitmapdecodeResource(Resourcesres,intid) //从资源文件读取图片

+publicstaticBitmapdecodeResource(Resourcesres,intid,Optionsopts)

+publicstaticBitmapdecodeByteArray(byte[]data,intoffset,intlength) //从数组读取图片

+publicstaticBitmapdecodeByteArray(byte[]data,intoffset,intlength,Optionsopts)

+publicstaticBitmapdecodeFileDescriptor(FileDescriptorfd) //从文件读取文件与decodeFile不同的是这个直接调用JNI函数进行读取效率比较高

+publicstaticBitmapdecodeFileDescriptor(FileDescriptorfd,RectoutPadding,Optionsopts)

*Bitmap.ConfiginPreferredConfig:

*

枚举变量(位图位数越高代表其可以存储的颜色信息越多,图像越逼真,占用内存越大)

+publicstaticfinalBitmap.ConfigALPHA_8 //代表8位Alpha位图每个像素占用1byte内存

+publicstaticfinalBitmap.ConfigARGB_4444 //代表16位ARGB位图每个像素占用2byte内存

+publicstaticfinalBitmap.ConfigARGB_8888 //代表32位ARGB位图每个像素占用4byte内存

+publicstaticfinalBitmap.ConfigRGB_565 //代表8位RGB位图每个像素占用2byte内存

Android中一张图片(BitMap)占用的内存主要和以下几个因数有关:

图片长度,图片宽度,单位像素占用的字节数。

一张图片(BitMap)占用的内存=图片长度*图片宽度*单位像素占用的字节数。

三、Bitmap加载方式

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

1.从本地(SDcard)文件读取

方式一

/**

*获取缩放后的本地图片

*

*@paramfilePath文件路径

*@paramwidth宽

*@paramheight高

*@return

*/

publicstaticBitmapreadBitmapFromFile(StringfilePath,intwidth,intheight){

BitmapFactory.Optionsoptions=newBitmapFactory.Options();

options.inJustDecodeBounds=true;

BitmapFactory.decodeFile(filePath,options);

floatsrcWidth=options.outWidth;

floatsrcHeight=options.outHeight;

intinSampleSize=1;

if(srcHeight>height||srcWidth>width){

if(srcWidth>srcHeight){

inSampleSize=Math.round(srcHeight/height);

}else{

inSampleSize=Math.round(srcWidth/width);

}

}

options.inJustDecodeBounds=false;

options.inSampleSize=inSampleSize;

returnBitmapFactory.decodeFile(filePath,options);

}

方式二(效率高于方式一)

/**

*获取缩放后的本地图片

*

*@paramfilePath文件路径

*@paramwidth宽

*@paramheight高

*@return

*/

publicstaticBitmapreadBitmapFromFileDescriptor(StringfilePath,intwidth,intheight){

try{

FileInputStreamfis=newFileInputStream(filePath);

BitmapFactory.Optionsoptions=newBitmapFactory.Options();

options.inJustDecodeBounds=true;

BitmapFactory.decodeFileDescriptor(fis.getFD(),null,options);

floatsrcWidth=options.outWidth;

floatsrcHeight=options.outHeight;

intinSampleSize=1;

if(srcHeight>height||srcWidth>width){

if(srcWidth>srcHeight){

inSampleSize=Math.round(srcHeight/height);

}else{

inSampleSize=Math.round(srcWidth/width);

}

}

options.inJustDecodeBounds=false;

options.inSampleSize=inSampleSize;

returnBitmapFactory.decodeFileDescriptor(fis.getFD(),null,options);

}catch(Exceptionex){

}

returnnull;

}

2.从输入流中读取文件(网络加载)

/**

*获取缩放后的本地图片

*

*@paramins输入流

*@paramwidth宽

*@paramheight高

*@return

*/

publicstaticBitmapreadBitmapFromInputStream(InputStreamins,intwidth,intheight){

BitmapFactory.Optionsoptions=newBitmapFactory.Options();

options.inJustDecodeBounds=true;

BitmapFactory.decodeStream(ins,null,options);

floatsrcWidth=options.outWidth;

floatsrcHeight=options.outHeight;

intinSampleSize=1;

if(srcHeight>height||srcWidth>width){

if(srcWidth>srcHeight){

inSampleSize=Math.round(srcHeight/height);

}else{

inSampleSize=Math.round(srcWidth/width);

}

}

options.inJustDecodeBounds=false;

options.inSampleSize=inSampleSize;

returnBitmapFactory.decodeStream(ins,null,options);

}

3.Resource资源加载

Res资源加载方式:

publicstaticBitmapreadBitmapFromResource(Resourcesresources,intresourcesId,intwidth,intheight){

BitmapFactory.Optionsoptions=newBitmapFactory.Options();

options.inJustDecodeBounds=true;

BitmapFactory.decodeResource(resources,resourcesId,options);

floatsrcWidth=options.outWidth;

floatsrcHeight=options.outHeight;

intinSampleSize=1;

if(srcHeight>height||srcWidth>width){

if(srcWidth>srcHeight){

inSampleSize=Math.round(srcHeight/height);

}else{

inSampleSize=Math.round(srcWidth/width);

}

}

options.inJustDecodeBounds=false;

options.inSampleSize=inSampleSize;

returnBitmapFactory.decodeResource(resources,resourcesId,options);

}

此种方式相当的耗费内存建议采用decodeStream代替decodeResource可以如下形式:

publicstaticBitmapreadBitmapFromResource(Resourcesresources,intresourcesId,intwidth,intheight){

InputStreamins=resources.openRawResource(resourcesId);

BitmapFactory.Optionsoptions=newBitmapFactory.Options();

options.inJustDecodeBounds=true;

BitmapFactory.decodeStream(ins,null,options);

floatsrcWidth=options.outWidth;

floatsrcHeight=options.outHeight;

intinSampleSize=1;

if(srcHeight>height||srcWidth>width){

if(srcWidth>srcHeight){

inSampleSize=Math.round(srcHeight/height);

}else{

inSampleSize=Math.round(srcWidth/width);

}

}

options.inJustDecodeBounds=false;

options.inSampleSize=inSampleSize;

returnBitmapFactory.decodeStream(ins,null,options);

}

BitmapFactory.decodeResource加载的图片可能会经过缩放,该缩放目前是放在Java层做的,效率比较低,而且需要消耗java层的内存。

因此,如果大量使用该接口加载图片,容易导致OOM错误

BitmapFactory.decodeStream不会对所加载的图片进行缩放,相比之下占用内存少,效率更高。

这两个接口各有用处,如果对性能要求较高,则应该使用decodeStream;如果对性能要求不高,且需要Android自带的图片自适应缩放功能,则可以使用decodeResource。

2.Assets资源加载方式:

/**

*获取缩放后的本地图片

*

*@paramfilePath文件路径,即文件名称

*@return

*/

publicstaticBitmapreadBitmapFromAssetsFile(Contextcontext,StringfilePath){

Bitmapimage=null;

AssetManageram=context.getResources().getAssets();

try{

InputStreamis=am.open(filePath);

image=BitmapFactory.decodeStream(is);

is.close();

}catch(IOExceptione){

e.printStackTrace();

}

returnimage;

}

4.从二进制数据读取图片

publicstaticBitmapreadBitmapFromByteArray(byte[]data,intwidth,intheight){

BitmapFactory.Optionsoptions=newBitmapFactory.Options();

options.inJustDecodeBounds=true;

BitmapFactory.decodeByteArray(data,0,data.length,options);

floatsrcWidth=options.outWidth;

floatsrcHeight=options.outHeight;

intinSampleSize=1;

if(srcHeight>height||srcWidth>width){

if(srcWidth>srcHeight){

inSampleSize=Math.round(srcHeight/height);

}else{

inSampleSize=Math.round(srcWidth/width);

}

}

options.inJustDecodeBounds=false;

options.inSampleSize=inSampleSize;

returnBitmapFactory.decodeByteArray(data,0,data.length,options);

}

四、Bitmap|Drawable|InputStream|Byte[]之间进行转换

Drawable转化成Bitmap

publicstaticBitmapdrawableToBitmap(Drawabledrawable){

Bitmapbitmap=Bitmap.createBitmap(drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight(),drawable.getOpacity()!

=PixelFormat.OPAQUE?

Bitmap.Config.ARGB_8888:

Bitmap.Config.RGB_565);

Canvascanvas=newCanvas(bitmap);

drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight());

drawable.draw(canvas);

returnbitmap;

}

drawable的获取方式:

Drawabledrawable=getResources().getDrawable(R.draw

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 营销活动策划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1