美文网首页
浅谈性能优化-图片优化

浅谈性能优化-图片优化

作者: 大苏打6815 | 来源:发表于2019-05-13 19:37 被阅读0次

    现在一线企业做开发,什么腾讯、网易、京东肯定都是要对于图片进行压缩的。比如我们平常用的QQ、微信,用了一个月之后,我们会发现内存空间会少个一两个G,我们要是不做压缩,空间的占用率就会越来越高。还是写一个小demo吧,主要是理解这种思想。

    安卓的默认Bitmap图片格式是ARGB_8888,我们以后自己要选择RGB_565,腾讯所有的项目,全部是用的RGB_565.这样比较节省内存一些。RGB_4444已经不怎么用了,它处理的颜色比较少。

    image.png

    我现在有一张图片放在mipmap里面的,从代码log里面可以看出来图片大小是284X349,内存大小是396464.我写代码一般icon或者图标都喜欢放mipmap,如果这张图片放在drawble文件夹里面,安卓会自动做处理,这张图片可能有6M左右(我自己试过),那我多加载几张,岂不是就玩完了,当然了,不是说drawble里面不能放图片,根据业务需求来,闪屏什么的可以放drawble在里面,小图标放mipmap。刚刚只是做了个放不同文件夹的一个实验去看图片所占内存大小.

    284*349像素点数量(默认格式是8888),每一个像素目前占四个字节的内存空间X4就为396464就能对应上了

    比如微信上面,我们要加载很多用户的头像,这个头像是80X80,那我们可不可以把这张图片,很多地方不需要的像素点去压缩呢?然后再让我们的屏幕来自己进行缩放。我们稍后单独写一个类来处理调整它的尺寸。ImageResize

    回过头来我们通过点击BitmapFactory.decodeResource进去看到源码(记得载入源码哦),可以看到它在解码的时候bm=decodeResourceStrem(res,value,is,null,opts),通过opts=new Options()它里面两个成员的值来进行缩放控制的,所以我们也可以自己去操纵它这个编码。
    decodeResource代表解码控制参数
    opts.inDensity表示像素密度,根据我们的drawble目录进行计算
    opts.inTargetDensity 画到屏幕上的像素密度

    工具类:
    public class ImageResize {
        public static Bitmap resizeBitmap(Context context, int id, int maxW, int maxH, boolean hasAlpha) {
            Resources resources = context.getResources();
            BitmapFactory.Options options = new BitmapFactory.Options();
            //需要拿得到系统处理的信息  比如解码出宽高,....
            options.inJustDecodeBounds = true;
            //我们把原来的解码参数改了再去生成bitmap
            //加了options.inJustDecodeBounds = true;
            //我们只能得到这张图片的解码信息,这里并不能直接生成bitmap的
            BitmapFactory.decodeResource(resources, id, options);
            //取到宽高
            int w = options.outWidth;
            int h = options.outHeight;
            //设置缩放系数
            //maxW,maxH是自己定义的尺寸,w,h是解码出来的宽高(我不一定要按照解码的宽高来,因此要缩放)他们的比例最接近2的多少倍
            options.inSampleSize = calcuteInSampleSize(w, h, maxW, maxH);
    
           //如果不需要Alpha通道,那么可以改成RGB_565进行压缩啊,上面之前说了,这里只占两个字节,比8888或者4444要好
            if(!hasAlpha){
                options.inPreferredConfig=Bitmap.Config.RGB_565;
            }
            options.inJustDecodeBounds=false;
            return BitmapFactory.decodeResource(resources,id,options);
    
    
        }
    
        //返回结果是原来解码的图片的大小  是我们需要的大小的   最接近2的几次方倍
        private static int calcuteInSampleSize(int w, int h, int maxW, int maxH) {
            int inSampleSize = 1;
            if (w > maxW && h > maxH) {
                inSampleSize = 2;
                while (w / inSampleSize > maxW && h / inSampleSize > maxH){
                    inSampleSize*=2;
                }
            }
            inSampleSize/=2;
            return inSampleSize;
        }
    }
    

    calcuteInSampleSize这个方法的意义就计算最接近自己定义图片大小的2的几次方倍。打个比方,你自己定义的是8080,安卓加载的图片解析器解析出来的是10001000,那么要最接近8080就是要缩小2的3次方也就是8倍。最后成了125125的像素。我们就缩小了8倍。

    处理前后对比以下log:
    image.png

    之前图片是284X349,内存大小是396464.大约0.3M
    压缩之后是71X87, 内存大小:12354大约0.01M
    所以压缩效果还是比较明显的。
    在不同分辨率手机上面,图片宽高有可能不一样。

    图片压缩还包含其他很多种方式,比如LIBJEPG,是用的NDK方式,里面也会涉及到哈夫曼编码格式和算法
    这个再之后的NDK架构的学习中会讲到的。今天仅仅是在java层把图片压缩这个流程先理解,大概思路就是这样。

    相关文章

      网友评论

          本文标题:浅谈性能优化-图片优化

          本文链接:https://www.haomeiwen.com/subject/bhhraqtx.html