Android图片常见问题处理

来源:互联网 发布:网络电视tv版哪个好 编辑:程序博客网 时间:2024/05/20 07:37

图片常见问题处理

  • 图片占用的内存计算

图片宽度 * 图片高度 * 单位像素占用的字节

单位像素占用的字节和Bitmap.Config有关,常用的有RGB_565和ARGB_8888。RGB_565占2个字节,ARGB_8888占4个字节支持透明度,RGB_565表示的颜色值没有ARGB_8888的多,RGB_565不支持透明度。

  • 如何处理图片占用内存过大导致内存溢出

通过图片占用内存的计算公式可以得知,有两个方法减小图片占用的内存:

  1. 设置Bitmap.Config为RGB_565,这样图片占用的内存为ARGB_8888的一半。
BitmapFactory.Options option = new BitmapFactory.Options();option.inPreferredConfig = Config.RGB_565;Bitmap bitmap = BitmapFactory.decodeFile(imgPath, option);
  1. 减小图片的高度和宽度
BitmapFactory.Options option = new BitmapFactory.Options();//值为0.5代表高度和宽度缩小一半,值为1表示不变option.inSampleSize = 0.5;Bitmap bitmap = BitmapFactory.decodeFile(imgPath, option);
  • 实际应用

  1. 实际开发中,我们一般不知道待加载的图片的高度和宽度,如果想让内存中图片的高度和宽度低于200px从而减少图片占用的内存,我们如何设置inSampleSize的值呢?BitmapFactory.Options提供了inJustDecodeBounds参数。当需要获取Bitmap的宽度和高度的时候,把inJustDecodeBounds设置为true,Bitmap创建好后,是不占用内存的,这样可以获取到高度和宽度;当需要获取可以显示的Bitmap时候,再把inJustDecodeBounds设置为false。下面是我项目中封装的方法:
public static Bitmap ratio(String imgPath, float width, float height) {    BitmapFactory.Options newOpts = new BitmapFactory.Options();    // 开始读入图片,此时把options.inJustDecodeBounds 设回true,即只读边不读内容    newOpts.inJustDecodeBounds = true;    newOpts.inPreferredConfig = Config.RGB_565;    Bitmap bitmap = BitmapFactory.decodeFile(imgPath, newOpts);    newOpts.inJustDecodeBounds = false;    int w = newOpts.outWidth;    int h = newOpts.outHeight;    // 想要缩放的目标尺寸    float hh = height;    float ww = width;    // 计算缩放比例    int be = 1;// be=1表示不缩放    if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放        be = (int) (newOpts.outWidth / ww);    } else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放        be = (int) (newOpts.outHeight / hh);    }    if (be <= 0)        be = 1;    newOpts.inSampleSize = be;// 设置缩放比例    // 开始压缩图片,注意此时已经把options.inJustDecodeBounds 设回false了bitmap = BitmapFactory.decodeFile(imgPath, newOpts);// 这里再进行质量压缩的意义不大,反而耗资源,删除return bitmap;}
  1. 实际开发中,可能需要我们压缩图片的存储大小,比如2M压缩到1M,这叫质量压缩。质量压缩的是图片在存储空间中的大小,和图片加载到内存中占用的内存大小无关。
/*** 存储Bitmap,并质量压缩,不大于maxSize(kb)** @param image* @param outPath* @param maxSize**/public static void compressAndGenImage(Bitmap image, String outPath,int maxSize) throws IOException {    ByteArrayOutputStream os = new ByteArrayOutputStream();    // 压缩度,100为不压缩    int options = 100;    image.compress(Bitmap.CompressFormat.JPEG, options, os);    // 循环压缩    while (os.toByteArray().length / 1024 > maxSize) {        // Clean up os        os.reset();        // 每次递减10        options -= 10;        image.compress(Bitmap.CompressFormat.JPEG, options, os);    }    FileOutputStream fos = new FileOutputStream(outPath);      fos.write(os.toByteArray());    fos.flush();    fos.close();}
0 0