Bitmap内存管理与APK瘦身九道程序小结(八)

一、Bitmap内存管理与优化

  1. 质量压缩

    • BitmapFactory.decodeFile()

    • BitmapFactory.decodeResource()

    • BitmapFactory.decodeStream()

    • inDensity :Bitmap的像素密度

    • 原理:通过算法扣掉了图片中的一些某些点附近相近的像素,达到降低质量减少文件大小的目的

      BitmapFactory.Options options = new BitmapFactory.Options();
      Bitmap bitmap = BitmapFactory.decodeFile(path,options);
      //压缩图片 降低图片的质量 视觉效应,少了一个亮级,省流量,加载到内存,能不能省内存呢?
      compressImageToFile(bitmap,new File(...));
      
      public static void compressImageToFile(Bitmap bmp,File file) throws Exception{
          int quality = 50;// 0 ~ 100
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          bmp.compress(Bitmap.CompressFormat.JPEG,quality,baos);
          FileOutputSteam fos = new FileOutputStream(file);
          fos.write(baos.toByteArray());
          fos.flush();
          fos.close();
      }
      
    • 注意,它只能实现对File文件的影响,对加载这个图片出来的Bitmap内存是无法节省的,因为Bitmap在内存中的大小是按照像素计算的,也就是width*height,质量压缩并不会改变Bitmap的真实像素

    • 使用场景:将图片压缩后保存到本地或者将图片上传到服务器

  2. 尺寸压缩

    • 原理:通过减少单位尺寸的像素值,真正意义上的降低像素

    • public static void compressBitmapToFileBySize(Bitmap bmp,File file){
          int ratio = 4;//压缩尺寸的倍数,值越大,图片的尺寸就越小
          Bitmap result = Bitmap.createBitmap(bmp.getWidth()/ratio,bmp.getHeight()/ratio,Bitmap.Config.ARGE_8888);
          Canvas canvas = new Canvas(result);
          RectF rect = new RectF(0,0,bmp.getWidth()/ratio,bmp.getHeight()/ratio);
          canvas.drawBitmap(bmp,null,rect,null);
          
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          result.compress(Bitmap.CompressFormat.JPEG,100,baos);
          FileOutputStream fos = new FileOutputStream(file);
          fos.write(baos.toByteArray());
          fos.flush();
          fos.close();
      }
      
  3. 采样率压缩

    int inSampleSize = 8;//数值越高,图片像素越低
    BitmapFactory.Options options = new BitmapFatcory.Options();
    options.inJustDecodeBounds = true;//为true不会真正加载图片
    options.inSampleSize = inSampleSize;//这里计算采样率
    options.inJustDecodeBounds = false;
    Bitmap bitamp = BitampFactory.decodeFile(filePath,options);
    
  4. IOS拍照1M的图片要比安卓拍照出来的5M图片还清楚

    • 图片引擎 95年JPEG处理引擎 libjpeg.turbo 官网,用于最初的在PC上面处理图片的引擎
    • 05年 skia 开发了一套skia引擎,基于JPEG的二次开发,便于浏览器的使用
    • 安卓上面用的什么引擎? skia引擎,阉割版 谷歌拿了skia,去掉哈夫曼算法,采用定长编码算法
    • 导致图片处理后文件变大了
    • 理由:当时由于CPU和内存在手机上都非常吃紧,性能差,由于哈夫曼算法非常吃CPU
    • 优化:绕过安卓Bitmap API层,自己编码
    • 哈夫曼算法 用字符在文件中出现的频率表来建立一个用 0,1串表示各字符的最优表示方式
    • 一个像素点包含四个信息(argb):alpha red green blue
    • abcde
    • a 001 b 010 c 011 d 100 e 101
    • 加权信息编码
    • a 80% b 10 % c 10 % d 0% e 0%
    • 编码优化 a 01 b 10 c 01
    • 权重(扫描图片信息,每个像素包括ARGB)
    • 实现 利用libjpeg库

二、APK瘦身九道程序(代码混淆 webp svg 资源压缩 lint so库 对齐/zip)

  1. SVG矢量图(常用于小图片,节省内存和空间)

    • 解决问题:UI需要为同一张图片准备不同尺寸

    • 创建步骤 res - new -vector asset ,然后可以选择AS自带的资源,也可以导入SVG或者PSD(不支持渐变和透明)

    • 5.0以下系统兼容,app的build.gradle的defaultConfig里进行如下配置,打包时会将SVG生成相应文件夹下的png图片

      vectorDrawables.generatedDensities('xhdpi','xxhdpi');
      
    • 5.0以上系统配置

      vectorDrawales.useSupportLibrary=true
      use:
      app:srcCompat="@drawable/ic_test" 
      
  2. Tint着色器

    • tint + selector在4.4系统会Crash
    • 解决问题:同一张图片需要不同颜色
  3. string.xml资源配置

    • 默认情况下,打包时会包含各国语言的基础方案,往往一个APP并不需要支持多国语言

      //只保留简体中文和繁体字
      resConfigs('zh-rCN','zh-rTN')
      
    • 重新打包后,resources.arsc可能会减少一般体积,这些语言是在support-v7包里产生的

  4. so库打包配置

    • 移除无用的cpu架构的so库

      ndk{
          abiFilters('armeabi-v7a')
      }
      
    • 如果APP是面向工业级,或者用户设备繁杂,比如要支持PDA,这种情况就不能这么做了

  5. 移除无用资源

    • 一键移除,如果出现使用动态id使用资源会出现问题,不建议
    • Refactor - Remove Unused Resources
    • Analyze - Run Inspection by Name - unused resources
  6. 代码混淆

    pass
    
  7. 资源压缩

    shrinkResources true
    
    • 开启后,发现未引用的资源会被压缩,布局代码内容消失

    • 如果需要指定文件不被压缩,需要在res下raw下新建keep.xml

      <?xml version="1.0" encoding="utf-8"?>
      <resources xmlns:tools="http://schemas.android.com/tools"
          tools:keep="@layout/activity_main2"
          tools:shrinkMode="strict" />
      
    • 有些代码会在运行期间引用,所以需要在keep里,使其不被压缩

      tools:keep="@layout/activity_main2,@layout/activity_main3"
      
  8. webp

    • AS里直接对文件图片右键,convert to webp ,视觉上不会有损失
  9. zipalign对齐

  10. 资源混淆(ant/aapt/aapt2)

    • 微信和美团方案,针对resources.arsc文件,编译前和编译后做处理
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值