zoukankan      html  css  js  c++  java
  • Android加载大图片(压缩)

    转载自http://blog.csdn.net/junjx/article/details/7798604

    在Android开发中,我们经常需要加载图片。但是图片的尺寸往往会很大,如果我们要的是比较小的图片,在Android有限的内存下,我们显然不能把大尺寸的图片放到内存里,这样不但效率降低,而且会导致java.lang.OutOfMemory异常,相信很多朋友都遇到过这样的问题,那么该怎么解决这一问题呢?其实在Android官方文档中早已给出了解决的方案。

    一、读Bitmap的尺寸和类型

        BitmapFactory类提供一系列的方法 (decodeByteArray(),decodeFile(),decodeResource(), etc.)从资源中创建一个Bitmap。可以在这些方法中选择适当的方法对图片资源进行译码。然而这些方法会很容易导致OutOfMemoryError异常。每种类型的解码方法都有一些附加的属性,你可以基于BitmapFactory.Options类提供的方法定义指定的解码方式。

    设置inJustDecodeBounds属性为true,避免分配内存,返回一个null的Bitmap对象(包含outWidth,outHeight andoutMimeType),这样就可以读取图片的尺寸和类型了。

    [java] view plaincopy
     
    1. BitmapFactory.Options options = new BitmapFactory.Options();  
    2. options.inJustDecodeBounds = true;  
    3. BitmapFactory.decodeResource(getResources(), R.id.myimage, options);  
    4. int imageHeight = options.outHeight;  
    5. int imageWidth = options.outWidth;  
    6. String imageType = options.outMimeType;  


    二、加载一个缩小版到内存

    现在我们已经获取了图片的大小,接下来我们该考虑是加载原图到内存,还是加载一张缩略图到内存。这有几点需要考虑的:

    估算加载图片占用内存的大小

    你打算在你的程序中给分出多少内存来加载图片

    你加载到目标组件图片的尺寸大小如何

    当前设备的屏幕的尺寸和密度大小

    例如,我们要把一张1024x768像素的图片加载到一个128x96像素的ImageView里面,我们应该告诉解码员(decoder)加载一张子图到内存,这样我们就需要设置BitmapFactory.Options对象的inSampleSize属性,例如一张2048x1536分辨率的图片,如果设置inSampleSize=4,将会产生一张分辨率为512x384的图片,加载这张子图到内存只需要消耗0.75MB的内存,而加载原图却需要12MB的内存(假设bitmap配置是ARGB_8888)。以下是代码是根据图片的大小及子图的尺寸动态计算
    imSampleSize的值的方法。

    [java] view plaincopy
     
    1. public static int calculateInSampleSize(  
    2.             BitmapFactory.Options options, 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.         if (width > height) {  
    10.             inSampleSize = Math.round((float)height / (float)reqHeight);  
    11.         } else {  
    12.             inSampleSize = Math.round((float)width / (float)reqWidth);  
    13.         }  
    14.     }  
    15.     return inSampleSize;  
    16. }  


    接着,首先设置inJustDecodeBounds=true,通过options设置inSampleSize的值再设置inJustDecodeBounds=false:

    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);
    }

    这样我们就能方便的得到一张分辨率为100x100的子图了:

    mImageView.setImageBitmap(
        decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));

    你可以用类似的方法,根据你的需要采用其他的译码方法来处理图片。

  • 相关阅读:
    Java Native Method
    SQL语句优化
    Ibatis的环境搭建以及遇到的问题解决
    Java 构建器
    SpringMVC自定义视图 Excel视图和PDF视图
    java 枚举的常见使用方法
    mysql 根据某些字段之和排序
    MFC The Screen Flickers When The Image Zoomed
    How To Debug Qmake Pro File
    Gcc And MakeFile Level1
  • 原文地址:https://www.cnblogs.com/zyppac/p/3794504.html
Copyright © 2011-2022 走看看