阅读 49

Bitmap 处理 之加载大的Bitmap

  • 流畅的加载大的Bitmap

    原文连接

    http://developer.android.com/intl/zh-CN/training/displaying-bitmaps/load-bitmap.html#read-bitmap

    在处理Bitmap的过中经常遇到的问题是OOM,尤其是在加载像素比较大的bitmap时,出现这种问题的概率比较高。在加载图片的时候,就要考虑是否真的需要那么大像素的bitmap,如果要显示的ImageView的大小是120x140,但是要加载的资源的图片是1024X768的,这时候如果直接加载资源很容易出现OOM的问题,如果在加载图片之前能够知道图片的像素的大小,然后在适当的压缩处理,然后在显示出来,这样OOM的问题就比较不容易出现。

    读取Bitmap的大小和类型

    BitmapFactory提供了很多方法来解析方法(decodeByteArray(), decodeFile(), decodeResource()等等)来创建bitmap,你可以选择一个合适的方法来创建bitmap,但是这样直接的创建bitmap和容易引起OOM,BitmapFactory还提供一组配套的方法来创建bitmap,需要加上BitmapFactory.Options的参数,在显示bitmap之前事先读取bitmap的大小和类型:

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(getResources(), R.drawable.myimage, options);
    int imageHeight = options.outHeight;
    int imageWidth = options.outWidth;
    String imageType = options.outMimeType;


    将BitmapFactory.Options的inJustDecodeBounds设置为true,可以在解析bitmap之前获得bitmap的大小和类型

    压缩bitmap之后,再加载到内存

    在显示bitmap之前,需要获得目标显示的bitmap的大小和要加载的bitmap的大小,然后计算出来一个合适的压缩比,把通过压缩过的bitmap加载到内存中,下面是一个封装的方法,来计算合适的压缩比

     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;
    
           }
    
           return inSampleSize;
    
       }

    其中 reqWidth,reqHeight是目标的宽的和高度,height,width是资源的高度和宽的,然后计算出一个压缩的比例,使用最小的压缩比
    要使用这个方法,首先将inJustDecodeBounds 设置为true,解析获得资源的大小和类型,然后通过上面的方法获得压缩比,然后再将inJustDecodeBounds设置为false,通过计算出来的要所比来解析最终要显示的bitmap

     public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
    
           int reqWidth, int reqHeight) {
    
       // First decode with inJustDecodeBounds=true to check dimensions 
    
       final BitmapFactory.Options options = new BitmapFactory.Options();
    
       options.inJustDecodeBounds = true;
    
       BitmapFactory.decodeResource(res, resId, options);
    
       // Calculate inSampleSize
    
       options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    
       // Decode bitmap with inSampleSize set
    
       options.inJustDecodeBounds = false;
    
       return BitmapFactory.decodeResource(res, resId, options);
    
      }


    例子: imageView的显示,ImageView要显示的图像的大小是100X100,实际的图像可能不是100X100,通过上面的方法做一下压缩处理,这样就避免出现OOM的问题

    mImageView.setImageBitmap(


       decodeSampledBitmapFromResource(getResources(), R.drawable.myimage, 100, 100));

    上面是通过解析decodeSampledBitmapFromResource 资源文件获得bitmap,当然还有其他的方法来获得bitmap

    public static Bitmap decodeSampledBitmapFromFile(String filename,
    
               int reqWidth, int reqHeighte) {
    
           // First decode with inJustDecodeBounds=true to check dimensions
    
           final BitmapFactory.Options options = new BitmapFactory.Options();
    
           options.inJustDecodeBounds = true;
    
           BitmapFactory.decodeFile(filename, options);
    
           // Calculate inSampleSize
            options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    
           // Decode bitmap with inSampleSize set
    
           options.inJustDecodeBounds = false;
    
           return BitmapFactory.decodeFile(filename, options);
       2.通过FileDescriptor获得bitmap
    public static Bitmap decodeSampledBitmapFromDescriptor(
    
               FileDescriptor fileDescriptor, int reqWidth, int reqHeight, ImageCache cache) {
    
           // First decode with inJustDecodeBounds=true to check dimensions
    
           final BitmapFactory.Options options = new BitmapFactory.Options();
    
           options.inJustDecodeBounds = true;
    
           BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
    
           // Calculate inSampleSize
    
           options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    
           // Decode bitmap with inSampleSize set
    
           options.inJustDecodeBounds = false;
    
           return BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
    
       }

    1. 通过文件获得bitmap

  • 相关阅读:
    实现JSON数据的存储和读取
    MediaPlayer类——播放视频和音乐
    网络编程浅析
    线程浅析
    I/O浅析
    fragment之间的信息交互——onActivityResult()不经过Activity
    命名规则
    String方法(一)
    面试小结
    找工作中......


文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐