android 图片缓存之 createBitmap

http://lipeng88213.iteye.com/blog/1845117


2013.04.10——— android 图片缓存之三createBitmap 
参考:http://blog.csdn.net/mujianwei/article/details/8016844 
http://onewayonelife.iteye.com/blog/1158698 
http://zhiweiofli.iteye.com/blog/905066 
http://blog.csdn.net/mzz5240/article/details/8722876 


我做一个应用需要非常频繁的加载很多图片,经常遇到内存溢出的问题 直接crash,这里有几个避免溢出的注意点,分享一下: 
1、颜色数修改 

   

Java代码   收藏代码
  1. * ALPHA_8:数字为8,图形参数应该由一个字节来表示,应该是一种8位的位图   
  2.     * ARGB_4444:4+4+4+4=16,图形的参数应该由两个字节来表示,应该是一种16位的位图.   
  3.     * ARGB_8888:8+8+8+8=32,图形的参数应该由四个字节来表示,应该是一种32位的位图.   
  4.     * RGB_565:5+6+5=16,图形的参数应该由两个字节来表示,应该是一种16位的位图.  

Bitmap.Config  ALPHA_8  Each pixel is stored as a single translucency (alpha) channel. 
Bitmap.Config  ARGB_4444  This field is deprecated. Because of the poor quality of this configuration, it is advised to use ARGB_8888 instead.  
Bitmap.Config  ARGB_8888  Each pixel is stored on 4 bytes. 
Bitmap.Config  RGB_565  Each pixel is stored on 2 bytes and only the RGB channels are encoded: red is stored with 5 bits of precision (32 possible values), green is stored with 6 bits of precision (64 possible values) and blue is stored with 5 bits of precision. 


创建bitmap默认是ARGB_8888,表示24bit颜色和8bit透明通道,如果不需要透明度 尽量修改为RGB_565 

Java代码   收藏代码
  1. opt.inPreferredConfig = Bitmap.Config.RGB_565;    


2、压缩图片 

有时候 我们需要的图片宽和高很小,这个时候 就不要把图片按原始尺寸显示出来,就可以缩小一下 

获取原始图片大小 

Java代码   收藏代码
  1. BitmapFactory.Options opt = new BitmapFactory.Options();    
  2.         opt.inJustDecodeBounds = true;              
  3.                 //设置只是解码图片的边距,此操作目的是度量图片的实际宽度和高度    
  4.         BitmapFactory.decodeFile(file, opt);    
  5.     
  6.         int outWidth = opt.outWidth; //获得图片的实际高和宽    
  7.         int outHeight = opt.outHeight;    



计算缩放比例 


Java代码   收藏代码
  1.  opt.inSampleSize = 1;                              
  2.         //设置缩放比,1表示原比例,2表示原来的四分之一....    
  3.         //计算缩放比    
  4. if (outWidth != 0 && outHeight != 0 && width != 0 && height != 0) {    
  5.     int sampleSize = (outWidth / width + outHeight / height) / 2;    
  6.     opt.inSampleSize = sampleSize;    
  7. }    
  8.   
  9. opt.inJustDecodeBounds = false;//最后把标志复原    



google官方给出的计算inSampleSize的大小 
Java代码   收藏代码
  1. public static int calculateInSampleSize(BitmapFactory.Options options,  
  2.             int reqWidth, int reqHeight) {  
  3.         // Raw height and width of image  
  4.         final int height = options.outHeight;  
  5.         final int width = options.outWidth;  
  6.         int inSampleSize = 1;  
  7.   
  8.         if (height > reqHeight || width > reqWidth) {  
  9.   
  10.             // Calculate ratios of height and width to requested height and width  
  11.             final int heightRatio = Math.round((float) height / (float) reqHeight);  
  12.             final int widthRatio = Math.round((float) width / (float) reqWidth);  
  13.   
  14.             // Choose the smallest ratio as inSampleSize value, this will guarantee a final image  
  15.             // with both dimensions larger than or equal to the requested height and width.  
  16.             inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;  
  17.   
  18.             // This offers some additional logic in case the image has a strange  
  19.             // aspect ratio. For example, a panorama may have a much larger  
  20.             // width than height. In these cases the total pixels might still  
  21.             // end up being too large to fit comfortably in memory, so we should  
  22.             // be more aggressive with sample down the image (=larger inSampleSize).  
  23.   
  24.             final float totalPixels = width * height;  
  25.   
  26.             // Anything more than 2x the requested pixels we'll sample down further  
  27.             final float totalReqPixelsCap = reqWidth * reqHeight * 2;  
  28.   
  29.             while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {  
  30.                 inSampleSize++;  
  31.             }  
  32.         }  
  33.         return inSampleSize;  
  34.     }  


3、options其他的设置 

Java代码   收藏代码
  1.  BitmapFactory.Options.inPurgeable;   
  2. *    
  3. * 如果 inPurgeable 设为True的话表示使用BitmapFactory创建的Bitmap   
  4. * 用于存储Pixel的内存空间在系统内存不足时可以被回收,   
  5. * 在应用需要再次访问Bitmap的Pixel时(如绘制Bitmap或是调用getPixel),   
  6. * 系统会再次调用BitmapFactory decoder重新生成Bitmap的Pixel数组。    
  7. * 为了能够重新解码图像,bitmap要能够访问存储Bitmap的原始数据。   
  8. *    
  9. * 在inPurgeable为false时表示创建的Bitmap的Pixel内存空间不能被回收,   
  10. * 这样BitmapFactory在不停decodeByteArray创建新的Bitmap对象,   
  11. * 不同设备的内存不同,因此能够同时创建的Bitmap个数可能有所不同,   
  12. 200个bitmap足以使大部分的设备重新OutOfMemory错误。   
  13. * 当isPurgable设为true时,系统中内存不足时,   
  14. * 可以回收部分Bitmap占据的内存空间,这时一般不会出现OutOfMemory 错误。   
  15. *    
  16. *    
  17. * inInputShareable 是否深拷贝  这个和inPurgeable一起出现  






Java代码   收藏代码
  1. public static Bitmap readBitMap(Context context, int resId) {  
  2.        BitmapFactory.Options opt = new BitmapFactory.Options();  
  3.        opt.inPreferredConfig = Bitmap.Config.RGB_565;  
  4.        opt.inPurgeable = true;  
  5.        opt.inInputShareable = true;  
  6.        InputStream is = context.getResources().openRawResource(resId);  
  7.        return BitmapFactory.decodeStream(is, null, opt);  
  8. }  


4、可以尽量用decodeStream 

因为源码里面 无论decodeFile还是decodeResourceStream都是调用了decodeStream 

为了避免java.lang.OutOfMemory 的异常,我们在真正decode图片之前检查它的尺寸,除非你确定这个数据源提供了准确无误的图片且不会导致占用过多的内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值