zoukankan      html  css  js  c++  java
  • 高效地加载图片(一) 高效地加载大图

    1.Read Bitmap Dimensions and Type 读取图片的尺寸和类型

    //创建一个Options,用于保存图片的参数 
    
    BitmapFactory.Options options = new BitmapFactory.Options(); 
    
    //设置是否只读取图片的参数信息 
    
    options.inJustDecodeBounds = true; 
    
    //由于inJustDecodeBounds被设置为了true,此处只会获得图片的参数信息 
    
    //而不会读取到Bitmap对象,也就不会占用内存 
    
    BitmapFactory.decodeResource(getResources(), R.id.myimage, options); 
    
    //获得图片的宽高以及类型 
    
    int imageHeight = options.outHeight; 
    
    int imageWidth = options.outWidth; 
    
    String imageType = options.outMimeType; 
    

    为了避免java.lang.OutOfMemory异常,在将一张图片解析为Bitmap对象之前,一定要检查它的尺寸.

    2.Load a Scaled Down Version into Memory 加载经过缩放的图片到内存中

    既然我们已经知道了图片的尺寸,我们就知道是否有必要将原图加载到内存中.我们可以有选择的将图片经过缩放后再加载到内存中.

    需要考虑的因素有以下几点:

    1.预估加载原图需要的内存大小

    2.你愿意给这张图片分配的内存大小

    3.要显示这张图片的控件的尺寸大小

    4.手机屏幕的大小以及当前设备的屏幕密度

    举例说明,如果你想要显示一张128×96像素的缩略图,则加载一张1024×768像素的图片是没有必要的.

    为了告诉解码器去加载一张经过缩放的图片,需要设置BitmapFactory.Options的inSampleSize参数.

    例如:一张图片的原始大小是2048×1536,如果将inSampleSize设置为4,则此时加载的图片大小为512×384,加载经过缩放后的图片只需要0.75MB的内存控件而不是加载全图时需要的12MB.

    以下是一个计算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;
    	// 默认缩放比例为1
        int inSampleSize = 1;
    
    	// 如果原始宽高其中之一大于指定的宽高,则需要计算缩放比例
    	// 否则,直接使用原图
        if (height > reqHeight || width > reqWidth) {
    
    		// 将图片缩小到一半
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
    
            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
    		// 计算inSampleSize的值,该值是2的次方,并且能够保证图片的宽高大于指定的宽高
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }
    
        return inSampleSize;
    }
    

    要想使用上述方法,首先要讲inJustDecodeBounds设置为true,读取到图片的尺寸信息,再经过计算得到的inSampleSize去解析图片

    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
            int reqWidth, int reqHeight) {
    
        // First decode with inJustDecodeBounds=true to check dimensions
    	// 此处将inJustDecodeBounds设置为true,则只解析图片的尺寸等信息,而不生成Bitmap
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
    
        // Calculate inSampleSize
    	// 此处计算需要的缩放值inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    
        // Decode bitmap with inSampleSize set
    	//将inJustDecodeBounds设置为false,以便于解析图片生成Bitmap
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }


  • 相关阅读:
    python--模块与包
    内置函数 的总结
    迭代器 生成器 列表推导式 生成器表达式的一些总结
    函数的有用信息 带参数的装饰器 多个装饰器装饰一个函数
    函数名的应用(第一对象) 闭包 装饰器
    动态参数 名称空间 作用域 作用域链 加载顺序 函数的嵌套 global nonlocal 等的用法总结
    函数的初识 函数的返回值 参数
    文件操作 常用操作方法 文件的修改
    遍历字典的集中方法 集合的作用 以及增删查的方法
    计算机硬件的小知识
  • 原文地址:https://www.cnblogs.com/chenchong/p/3692554.html
Copyright © 2011-2022 走看看