android之图片(bitmap)总结 持续学习中......

来源:互联网 发布:网络综合布线施工工序 编辑:程序博客网 时间:2024/06/05 15:59

写在前头

android开发工作中,对图片的处理其实让人挺头疼,对于bitamp也一直在学习中。现在这里记录一下,方便自己以后学习。

知识点:
1. 图片压缩
2. 图片占用内存大小及加载解析

对于图片的压缩(看了你可能觉得你有些地方一直存在误区哦)

android图片压缩之质量压缩。

之前一直以为图片的质量压缩可以减少oom的产生,其实不然,他只是在保证图片质量的同时减少了文件的大小,他其实不会改变占用的内存。质量压缩是在保持像素的前提下改变图片的位深及透明度等,来达到压缩图片的目的,经过它压缩的图片文件大小会有改变,但是导入成bitmap后占得内存是不变的。因为要保持像素不变,所以它就无法无限压缩,到达一个值之后就不会继续变小了。显然这个方法并不适用与缩略图,其实也不适用于想通过压缩图片减少内存的使用,仅仅适用于想在保证图片质量的同时减少文件大小的情况而已

质量压缩:

    //参数一 bitmap图片  参数2 你想要压缩后图片的最大值    public Bitmap compressImage(Bitmap image,int imageSize) {          ByteArrayOutputStream baos = new ByteArrayOutputStream();          //质量压缩方法,这里100表示压缩质量,100表示不压缩,把压缩后的数据存放到baos中          image.compress(Bitmap.CompressFormat.JPEG, 100, baos);        int options = 100;          //循环判断压缩后图片是否大于你设置的最大值,大于则继续压缩                 while ( baos.toByteArray().length / 1024>imageSize) {          //重置baos即清空baos             baos.reset();             //每次都减少5             options -= 5;            //这里压缩options%,把压缩后的数据存放到baos中              image.compress(Bitmap.CompressFormat.JPEG, options, baos);        }          //把压缩后的数据baos存放到ByteArrayInputStream中          ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());        //把ByteArrayInputStream数据生成图片          Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);        return bitmap;      } 

android图片压缩之大小压缩。

尺寸压缩是压缩图片的像素,一张图片所占内存的大小 图片类型*宽*高,通过改变三个值减小图片所占的内存,防止OOM(这才是防止oom的重要过程),当然这种方式可能会使图片失真

public Bitmap getSmallIcon(String filePath,int yourWidth,int yourHeight) {        BitmapFactory.Options opt= new BitmapFactory.Options();        //禁止为bitmap分配内存        opt.inJustDecodeBounds = true;        BitmapFactory.decodeFile(filePath, opt);        opt.inSampleSize = calculateInSampleSize(opt, yourWidth,yourHeight);        //允许为bitmap分配内存,得到压缩的bitmap图片        opt.inJustDecodeBounds = false;        Bitmap bitmap = BitmapFactory.decodeFile(filePath, opt);        return bitmap ;    }public static int calculateInSampleSize(BitmapFactory.Options options,int yourWidth, int yourHeight) {    //获取图片的长度,宽度和MIME属性        final int height = options.outHeight;        final int width = options.outWidth;        int inSampleSize = 1;        if (height > yourHeight|| width > yourWidth) {        // 计算出实际宽高和目标宽高的比率              final int heightRatio = Math.round((float) height / (float) yourHeight);            final int widthRatio = Math.round((float) width / (float) yourWidth);            // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高              // 一定都会大于等于目标的宽和高。              inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;        }        return inSampleSize;    }

图片占用内存大小及加载解析

自问:

  1. 手机进行屏幕适时,常想可不可以只切一套图适配所有的手机呢?
  2. 一张图片加载到手机中,占用内存到底有多少?
  3. 图片占用内存跟哪些东西有关?跟手机有关系么?同一张图片放在不同的dpi文件夹下内存占用会变化么?
  4. 如果是网络图片,加载到手机中,占用内存跟手机屏幕有关系么?

大神已经分析过了,如果你想看过程,请移步:
http://blog.csdn.net/smileiam/article/details/68946182
结论的话,看下面就够了!
结论:

1.在对手机进行屏幕适时,可以只切一套图适配所有的手机。    但是如果只切一套小图,那在高屏幕密度手机上,会对图片进行放大,这样图片占用的内存往往比切相应图片放在高密度文件夹下,占用的内存还要大。    那如果只切一套大图放在高幕文件夹下,在小屏幕密度手机上,会缩小显示,按道理是行得通的。但系统在对图片进行缩放时,会进行大量计算,会对手机的性能有一定的影响。同时如果图片缩放比较狠,可能导致图片出现抖动或是毛边。    所以最好切出不同比便的图片放在不同幕度的文件夹下,对于性能要求不大高的图片,可以只切一套大图;2.一张图片占用内存=图片长 * 图片宽 / (资源图片文件密度/手机屏幕密度)^2 * 每一象素占用字节数,所以图片占用内存跟图片本身大小、手机屏幕密度、图片所在的文件夹密度,图片编码的色彩格式有关;3.对于网络图片,在不同屏幕密度的手机上加载出来,占用内存是一样的。4.对于网络或是assets/手机本地图片加载,如果想通过设置Options里的inDensity或是inTargetDensity参数来调整图片的缩放比,必须两个参数均设置才能起作用,只设置一个,不会起作用。5.drawable和mipmap文件夹存放图片的区别,首先图片放在drawable-xhdpi和mipmap-xhdpi下,两者占用的内存是一样的,Mipmaps早在Android2.2+就可以用了,但是直到4.3 google才强烈建议使用。把图片放到mipmaps可以提高系统渲染图片的速度,提高图片质量,减少GPU压力。其他并没有什么区别。

写在后面

学习中也用过一些类似luban的第三方压缩框架,发现总会有一些问题,比如压缩多张图片anr等等,自己写的才是靠谱的嘿嘿。
如果你有好的想法,请告知。谢谢分享。

原创粉丝点击