insamplesize 用法可以是小数吗

android(21)
一、OOM异常是什么?产生OOM异常的原因
& & & & OOM(Out Of Memory--内存不够用了)
& & & & a、计算图片占用的内存大小:
& & & & & & & & & 1、 占用内存 = 图片的长度 * 图片的宽度 * 单位像素占用的字节数;
& & & & & & & & & 2、 单位像素占用的字节数是由BitmapFactory.Options的inPreferredConfig变量的值决定的:
& & & & & & & & & & & & A(alpha)--透明度,R(red)--红色,G(green)--绿色,B(blue)--蓝色,即三原色;如一张图片是720*1080,ARGB是一
& & & & & & & & & & & & 种色彩模式:&&
& & & & & & & & & & & & ① Bitmap.Config.ALPHA_8: 此时图片就只有alpha值,一个像素就只占用一个字节(8代表的是这个透明度占用8
& & & & & & & & & & & & & & &位,即一个字节),图片占用的内存大小:720*1080*1(字节)
& & & & & & & & & & & & ② Bitmap.Config.ARGB_4444: 即A、R、G、B 各占四个bit,总共就是4*4=16个bit= 2(字节),这种格式的图片看
& & & & & & & & & & & & & & &起来质量很差,已经不再使用,&图片占用的内存大小:720*1080*2(字节)
& & & & & & & & & & & & ③ Bitmap.Config.ALPHA_8888: 即A、R、G、B各占8个bit,总共就是4*8=32bit = 4(字节),这是一种高质量的图
& & & & & & & & & & & & & & 片,android手机上Bitmap默认的格式,图片占用的内存:720*1080*4(字节)
& & & & & & & & & & & & ④ Bitmap.Config.RGB_565 : 即 R、G、B 分别占用5、6、5个bit,总共:5+6+5=16bit=2(字节),这种格式的图片,
& & & & & & & & & & & & & & &不支持透明和半透明,图片质量也达到了效果,且占用内存相对来说较小,图片占用内存:720*1080*2(字节)
& & & & & b、 &一个应用程序,android系统一般会为它分配16MB的内存大小,,例如:三星s4后置摄像头像素1300万,则拍照后,照片
& & & & & & & & &的大小就是1300万*4(字节)(假设单位像素的字节数按4个字节),即49.6MB,远远超过了android系统分配给这个应
& & & & & & & & &用的内存,且这16MB不仅仅是用来存储图片的,所以如果不处理图片,直接加载图片的话,就会出现OOM异常。这是
& & & & & & & & &android开发中最常见的OOM异常。
二、解决OOM异常的方法:
& & & & & &a、改变图片的大小,即缩小图片,缩小图片的方法:
& & & & & & & & &方法一:利用Matrix来缩小图片
public Bitmap zoomBitmap(Bitmap bitmap) {
//获得Bitmap的高和宽
int bmpWidth = bitmap.getWidth();
int bmpHeight = bitmap.getHeight();
//这边假设imageView的宽和高是一样的
int imageViewHeight = imageViewW
//设置缩小比例,imageViewWidth 就是我们需要的宽度
double scale = (double) imageViewWidth / bmpW
double scaleH = (double) imageViewHeight/bmpH
//为了保证图片可以显示完全
if (scale&scaleH){
scale = scaleH;
Log.e(&缩放比例:&, &scale = & + scale);
//计算出长宽要缩放的比例
float scaleWidth = (float) (1 * scale);
float scaleHeight = (float) (1 * scale);
//产生resize后的Bitmap对象
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizeBmp =
resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bmpWidth, bmpHeight, matrix, true);
Log.e(&缩放后的图片的宽度:bitmapWidth=&, && + resizeBmp.getWidth());
//修改色彩模式
Bitmap zoomBitmap = resizeBmp.copy
(Bitmap.Config.RGB_565,false);
return zoomB
}& & & & & & & 优点:可以按任何比例来缩放,即缩放比例可以是小数;而Options.inSampleSize 只能是整数。
& & & & & & & 缺点:会耗费很大的内存,因为缩放后的图片的色彩模式是ARGB_8888,每个像素单位就是4个字节了;
& & & & & & & & & & & & 解决办法:修改色彩模式,如代码所示,这样虽然会生成一个Bitmap对象,但是总的消耗的内存还是减小的。
& & & & & & &方法二:利用BitmapFactory.Options进行缩放:
private Bitmap getimage(String srcPath) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
//开始读入图片,此时把options.inJustDecodeBounds 设回true了
newOpts.inJustDecodeBounds =
BitmapFactory.decodeFile(srcPath, newOpts);//此时返回bitmap为空,只有一些图片大小等信息;
//这时候设置false ,返回的bitmap就不是空的了
newOpts.inJustDecodeBounds =
int w = newOpts.outW
int h = newOpts.outH
//imageViewWidth和imageViewHeight是我们希望的宽和高
int hh = imageViewW
int ww = imageViewW
//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int be = 1;//be=1表示不缩放
if (w & h && w & ww) {//如果宽度大的话根据宽度固定大小缩放
be = (int) (newOpts.outWidth / ww);
} else if (w & h && h & hh) {//如果高度高的话根据宽度固定大小缩放
be = (int) (newOpts.outHeight / hh);
//be不能是小数,必须是整型的
if (be &= 0)
newOpts.inSampleSize =//设置缩放比例
//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
//直接返回,不用质量压缩也可以展示
}& & & & & & &优点:可以通过options.inJustDecodeBounds=true,来节省内存的开销
& & & & & & &缺点:options.inSampleSize只能是2的整数次幂,如果不是的话,就向下取最大的2的整数次幂
& & & &b、改变图片的质量,但是这样会造成图片看起来不清晰: &&private Bitmap compressQualityImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//100代表不压缩图片,把图片保存到baos中
pressFormat.JPEG, 100, baos);
int options = 100;
//500KB 就是我们能用的最大内存空间了
while (baos.toByteArray().length / 1024 & 500) {
//清空baos
baos.reset();
options -= 10;
if (options & 0) {
pressFormat.JPEG, options, baos);
//把压缩后的图片放在inBm中
ByteArrayInputStream inBm = new ByteArrayInputStream(baos.toByteArray());
//生成图片
Bitmap bitmap = BitmapFactory.decodeStream(inBm, null, null);
}& & & & c、目前我知道的最优方案,实际应用中也高高的
& & & & & & & 分析:当我们使用BitmapFactory.decodeResource()、decodeFile()等方法时,这些方法最终都是通过java层的
& & & & & & & & & & & & & createBitmap()方法来生成Bitmap的,这样就会消耗很多的内存;因此我们如果用BitmapFactory.decodeStream()来生成一个Bitmap对象时,无需调用java层的
& & & & & & & & & & & & & createBitmap()方法,而是直接调用JNI的nativeDecodeAsset()方法来完成,节省很多的内存空间,如果再加上图片的Config(色彩模式)参数(最好用
& & & & & & & & & & & & & Bitmap.Config.RGB_565)这样就更加有效地减少的内存的开销。
& & & & & & & &代码:
*相对来说最优生成Bitmap的方法
* @param context
* @param resId
图片的id,一般在drawable下的图片,代码中也有如何根据图片路径来构造流
public static Bitmap readBitmap(Context context, int resId) {
BitmapFactory.Options opt = new BitmapFactory.Options();
//最低位的配置
opt.inPreferredConfig = Bitmap.Config.RGB_565;
//inPurgeable设为true的话表示使用BitmapFactory创建的Bitmap用于存储Pixel的内存空间在系统内存不足时可以被回收
opt.inPurgeable =
//是否深拷贝???
opt.inInputShareable =
//1、drawable下的图片构造流的方法
InputStream is =
context.getResources().openRawResource(resId);
//2、根据路径构造流的方法
String picturePath = &..........&;
File file = new File(picturePath);
InputStream inputStream = new FileInputStream(file);
}catch (Exception e){
e.printStackTrace();
return BitmapFactory.decodeStream(is, null, opt);
}& & & & & d、注意:只用一次的Bitmap的记着回收,代码如下:
if(!bitmap.isRecycled()){
bitmap.recycle();//回收图片所占的内存
System.gc();//提醒系统及时回收
三、上面知识都是我的理解,肯定有很多不足,我们可以去学习下Fresco:&/facebook/fresco
参考资料:/plokmju/p/android_loadbigimage.html & &&& &&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1619次
排名:千里之外
原创:25篇
(2)(3)(9)(5)(1)(5)(2)(1)Android高效加载大图、多图解决方案_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
Android高效加载大图、多图解决方案
上传于||文档简介
&&A​n​d​r​o​i​d​高​效​加​载​大​图​、​多​图​解​决​方​案
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
下载文档到电脑,查找使用更方便
还剩2页未读,继续阅读
你可能喜欢

我要回帖

更多关于 insamplesize 的文章

 

随机推荐