`

2013.04.10——— android 图片缓存之三createBitmap

阅读更多
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、颜色数修改

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

创建bitmap默认是RGB_8888,表示24bit颜色和透明通道,如果不需要透明度 尽量修改为RGB_565
opt.inPreferredConfig = Bitmap.Config.RGB_565;  


2、压缩图片

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

获取原始图片大小
BitmapFactory.Options opt = new BitmapFactory.Options();  
        opt.inJustDecodeBounds = true;            
                //设置只是解码图片的边距,此操作目的是度量图片的实际宽度和高度  
        BitmapFactory.decodeFile(file, opt);  
  
        int outWidth = opt.outWidth; //获得图片的实际高和宽  
        int outHeight = opt.outHeight;  



计算缩放比例

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



google官方给出的计算inSampleSize的大小
public static int calculateInSampleSize(BitmapFactory.Options options,
            int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            // Calculate ratios of height and width to requested height and width
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);

            // Choose the smallest ratio as inSampleSize value, this will guarantee a final image
            // with both dimensions larger than or equal to the requested height and width.
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;

            // This offers some additional logic in case the image has a strange
            // aspect ratio. For example, a panorama may have a much larger
            // width than height. In these cases the total pixels might still
            // end up being too large to fit comfortably in memory, so we should
            // be more aggressive with sample down the image (=larger inSampleSize).

            final float totalPixels = width * height;

            // Anything more than 2x the requested pixels we'll sample down further
            final float totalReqPixelsCap = reqWidth * reqHeight * 2;

            while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
                inSampleSize++;
            }
        }
        return inSampleSize;
    }


3、options其他的设置

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






 public static Bitmap readBitMap(Context context, int resId) {
		   BitmapFactory.Options opt = new BitmapFactory.Options();
		   opt.inPreferredConfig = Bitmap.Config.RGB_565;
		   opt.inPurgeable = true;
		   opt.inInputShareable = true;
		   InputStream is = context.getResources().openRawResource(resId);
		   return BitmapFactory.decodeStream(is, null, opt);
	}


4、可以尽量用decodeStream

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

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

相关推荐

    2011.10.19(2)——— android 圆角与倒影

    3. 对新Bitmap的下半部分进行模糊处理,可以使用Bitmap.createBitmap的复制功能和PorterDuff.Mode.DST_IN模式来实现。 4. 将模糊后的下半部分翻转并绘制在新Bitmap的上半部分下方。 5. 将新Bitmap设置给ImageView。 ...

    2011.10.12(3)——— android Matrix学习02

    这篇博客“2011.10.12(3)——— android Matrix学习02”可能深入探讨了Matrix类的使用方法,虽然具体的细节没有给出,但我们可以根据Matrix的基本功能和常见用法来展开讨论。 1. **Matrix类的介绍**:Matrix是...

    Android下利用Bitmap切割图片

    切割图片通常指的是从原始图片中提取出一个矩形区域,这个操作在Android中可以通过Bitmap.createBitmap方法实现。以下是一个简单的示例,展示如何从Bitmap中裁剪出指定大小和位置的子Bitmap: ```java // 原始...

    2011.10.09——— android ImageView放大缩小(2)

    标题中的“2011.10.09——— android ImageView放大缩小(2)”指的是一个关于Android平台中ImageView组件的优化技术,特别是如何处理图片的缩放问题。在Android应用开发中,ImageView是用于显示图像的常见组件,但...

    安卓Android源码——安卓Android 图片缓存、加载器.zip

    本压缩包“安卓Android源码——安卓Android 图片缓存、加载器.zip”可能包含了关于如何在Android平台上实现图片缓存和加载机制的源代码示例,这对于理解Android应用性能优化至关重要。 首先,让我们探讨一下图片...

    安卓Android源码——安卓Android 图片缓存、加载器.rar

    Android 图片缓存和加载器的设计旨在优化用户体验,减少内存消耗,并提高应用的响应速度。下面将详细讨论这些概念以及如何在Android源码中实现它们。 首先,我们需要理解为什么图片缓存是必要的。在移动设备上,...

    安卓Android源码——android相册系统(用Matrix实现).rar

    Matrix可以很好地完成这些任务,通过`Bitmap.createBitmap()`方法结合变换矩阵,创建一个新的Bitmap对象。 3. **ImageView与Matrix**:在Android的UI组件中,ImageView可以显示图像,并支持触摸手势操作。当...

    安卓Android源码——android相册系统(用Matrix实现).zip

    3. **图片加载与显示**: 在Android中,通常使用ImageView来显示图片,而Bitmap类则用来表示位图。在处理大量图片时,需要考虑内存管理,避免因加载过多图片导致内存溢出。通常会使用像Picasso、Glide或 Fresco 这样...

    处理bitmap内存溢出问题

    在Android开发中,处理`Bitmap`内存溢出问题是一个常见的挑战,尤其是在处理高分辨率或大尺寸图片时。当应用程序尝试加载或操作一张超出虚拟机内存预算的`Bitmap`时,系统会抛出`java.lang.OutOfMemoryError: bitmap...

    Android Bitmap.getPixels的正确理解演示源码

    Android Bitmap.getPixels的正确理解演示源码,参考文章《Android Bitmap入门:getPixels的正确理解》

    安卓Android源码——(Bitmap位图渲染与操作).zip

    - **裁剪**:使用Bitmap.createBitmap()方法可以裁剪Bitmap的一部分。 - **合并**:可以将多个Bitmap拼接在一起,创建新的Bitmap。 - **颜色转换**:通过ColorFilter或者PorterDuff.Mode实现Bitmap颜色的变化。 ...

    Android源码——Google官网的图片缓存源码.7z

    本篇将围绕"Android源码——Google官网的图片缓存源码"这一主题,深入解析图片缓存的核心概念和技术。 首先,我们了解下图片缓存的基本原理。图片缓存通常分为内存缓存和磁盘缓存两部分。内存缓存利用Java的HashMap...

    安卓Android源码——android 安卓画廊 照片转换器.zip

    这需要对图像处理算法有深入了解,例如使用`Bitmap.createBitmap()`进行尺寸调整,`Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height)`进行裁剪。 6. **存储访问权限**:由于Android 6.0...

    安卓Android源码——android 安卓画廊 照片转换器.rar

    通过分析这个"安卓Android源码——android 安卓画廊 照片转换器.rar",开发者可以深入理解Android平台上的图片处理、用户界面设计以及多媒体数据的管理,这些是开发一款高效、用户友好的画廊应用的基础。同时,源码...

    安卓Android源码——常用图片特效处理源码.zip

    通过创建一个Rect对象定义裁剪区域,然后调用Bitmap.createBitmap()方法,传入原图、裁剪区域和变换模式,即可得到裁剪后的图片。 2. 图片缩放:Bitmap类的createScaledBitmap()方法可以用来缩放图片,它接受原始...

    Android中把bitmap存成BMP格式图片的方法

    首先,Android SDK提供了`Bitmap.compress()`方法来将Bitmap保存为JPEG或PNG格式,但不支持BMP。因此,我们需要自定义一个方法来处理BMP格式的转换。这个过程主要包括以下几个步骤: 1. **获取Bitmap的像素数据**:...

    Android图片缓存之Bitmap详解(一)

    Bitmap是Android平台中用于处理图像的核心类,它包含了对图像数据的存储和操作。Bitmap对象存储实际的像素数据,可以通过Bitmap对象进行图像的显示、裁剪、旋转、...在实现图片缓存框架时,这些基础知识更是必不可少。

    安卓Android源码——android gif模式和图片展现模式 图片展现神器.rar

    "安卓Android源码——android gif模式和图片展现模式 图片展现神器.rar"这个资源提供了关于如何在Android平台上处理GIF格式图像以及优化图片显示模式的源代码示例。 首先,我们要理解GIF(Graphics Interchange ...

    Android源码——Google官网的图片缓存源码.zip

    在Android开发中,图片缓存是一个非常重要的环节,它能够有效地提高应用的性能,减少网络请求,提升用户体验。Google官方提供了优秀的图片加载库,如Glide、Picasso等,它们都包含了高效的图片缓存机制。这里我们将...

    安卓Android源码——android gif模式和图片展现模式 图片展现神器.zip

    本资源“安卓Android源码——android gif模式和图片展现模式 图片展现神器.zip”提供了深入理解和实践Android系统中处理GIF动图以及各种图片展现模式的源代码示例。下面我们将详细探讨这些知识点。 1. **GIF支持**...

Global site tag (gtag.js) - Google Analytics