摘要:
     我们做Android应用的时候最不可避免的就是与图片打交道,而图片通常又是应用内存开销,影响性能的大头,因而这也是网上的帖子关于图片方面的内容热度比较高的原因之一。另外,发现身边的一些做Android应用开发的朋友,在处理图片这方面的问题的时候,基本就是“一把梭,拿起就干“,从网上拷贝了代码贴上去看到没报错了,就完事。缺乏深度的思考,孔子曰“学而不思则罔” ,这也就促使我冲动的写下该文。
一、图片大小
       了解图片大小之前,先说下图片的存放形式:本地文件、流和Bitmap三种,或许我们会疑问,流和Bitmap不都存放在内存当中吗,那岂不应该是同一种形式才对吗?实际上,都存放进内存,没错,但它们两者在内存中的数据结构是不一样的,即表示每个像素的数据是不相等的。那么三种形式图片的计算是怎样的?
       
       A、本地文件和流都是通过计算文件的长度得到图片的大小,如:
         File f = new File(path);
         long size = f.length();
         所以,本地文件的大小 = 图片流的大小,即本地存放一张1M的图片,通过流的方式读到内存当中,流的大小也是1M。
       B、Bitmap的大小 = bitmap.getRowBytes() * bitmap.getHeight() ,一行的字节数 x 高度。
       经常我们会看到,本地一张1M的图片以Bitmap的方式读到内存中,会比流的方式读到内存中大好几倍。这是因为,本地的图片通常都是通过Bitmap的方式压缩(有损或算法的压缩方式)保存到本地的。如,一张Bitmap.Config.ARGB_8888类型的图片以Bitmap.Config.RGB_565的类型保存到本地,那么保存后的图片大小就会比Bitmap在内存中的大小小很多,究其原因,就是他们表示每个像素的数据变了,后者没有alpha通道数据,不支持透明和半透明。到此,我觉得有必要让我们来了解一下Bitmap的Config类型: 
上面图是从官网截图下来的,然而,我再用我的理解来详说下,这几种类型的区别:
1、Bitmap.Config.ALPHA_8  表示图片只有alpha值,没有RGB值,1个像素占用一个字节 
2、Bitmap.Config.ARGB_4444 表示一个像素占用2个字节,alpha(A)值,Red(R)值,Green(G)值,Blue(B)值各占4个bites共16bites,即2个字节 
3、Bitmap.Config.ARGB_8888 表示一个像素占用4个字节,alpha(A)值,Red(R)值,Green(G)值,Blue(B)值各占8个bites,共32bites,即4个字节。(Android上Bitmap的默认格式) 
4、Bitmap.Config.RGB_565 表示一个像素占用2个字节,没有alpha(A)值,即不支持透明和半透明,Red(R)值占5个bites ,Green(G)值占6个bites ,Blue(B)值占5个bites,共16bites,即2个字节。
ok,了解了Bitmap图片不同类型所占据的内存字节数后,对于刚才上面提到的本地图片与Bitmap图片大小差异的问题,应该就迎刃而解了。
二、Bitmap的图片压缩
上面说到了图片的大小,实际上,图片的大小应该分为质量的大小和尺寸的大小。那么,Bitmap图片的压缩也应该包括质量的压缩和尺寸的压缩两种。
       
1、图片质量压缩
public static boolean saveImageFileToLoc(final File file, final Bitmap photoBitmap) {FileOutputStream fos = null;try {if (null != file) {fos = new FileOutputStream(file);if (null != fos) {photoBitmap.compress(Bitmap.CompressFormat.JPEG,75, fos);fos.flush();}return true;}} catch (IOException e) {return false;} finally {photoBitmap.recycle();try {if (null != fos) {fos.close();}} catch (IOException e) {e.printStackTrace();}}return false;
}
上面是对Bimtap图片进行质量的压缩,如果原来Bitmap的图片类型是Bitmap.Config.ARGB_8888,那么现在使用Bitmap.CompressFormat.JPEG的方式压缩,每个图片像素存储大小是会变小的,另外,compress这种方法的压缩,实际是一种算法(哈夫曼)的压缩,打个比方:原来用a b c d来存储一个像素,现在经过一定的算法计算后,使用另外一个或多个更小的字节来存储,从而达到压缩的作用,其中75就是计算压缩的程度。这种图片的压缩使用情景是,我们要保存一张图片、或上传图片到服务器的时候,对图片进行了压缩能有效的减少图片在手机当中存储空间,或上传的流量。那么,从这里看,图片最终存在在本地,图片的质量压缩与内存大小实际上是无关的。
2、图片尺寸压缩
public static Bitmap resizeBitmap(String imgPath, float pixelW, float pixelH) {BitmapFactory.Options newOpts = new BitmapFactory.Options();// 开始读入图片,此时把options.inJustDecodeBounds 设回true,即只读边不读内容newOpts.inJustDecodeBounds = true;newOpts.inPreferredConfig = Bitmap.Config.ARGB_8888;// Get bitmap info, but notice that bitmap is null nowBitmap bitmap = BitmapFactory.decodeFile(imgPath,newOpts);newOpts.inJustDecodeBounds = false;int w = newOpts.outWidth;int h = newOpts.outHeight;// 想要缩放的目标尺寸float hh = pixelH;// 设置高度为240f时,可以明显看到图片缩小了float ww = pixelW;// 设置宽度为120f,可以明显看到图片缩小了// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可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 ;
}
上面的压缩是根据指定的图片尺寸进行采样率的压缩,是把本地图片转到Bitmap,也即图片从本地到内存,同时本地的图片转Bitmap的过程中,因为不同的Bitmap类型,所占的内存就会有很大的差异,另外,不同的采样率会影响像素的个数,在每个像素占据内存大小一定的情况下,像素的个数直接决定了Bitmap图片占据内存的大小。所以,在使用场景当中,经常我们会出现OOM的问题,这个时候,我们就可以通过改变Bitmap的类型和采样率来降低内存的大小,从而避免出现图片的OOM问题。
    
 总结:本文只是通过对图片大小的介绍以及两种压缩方式的对比,来进一步说明我们使用图片压缩的过程中,对内存所产生的 影响,以及这两种Bitmap图片压缩方式的正确使用场景。

Android的Bitmap图片压缩与内存的关系相关推荐

  1. 【Android 内存优化】Android 原生 API 图片压缩原理 ( 哈夫曼编码开关 | 哈夫曼编码原理 | libjpeg-turbo 函数库 )

    文章目录 一. 哈夫曼编码开关 二. 哈夫曼编码原理 三. libjpeg-turbo 函数库 四. libjpeg-turbo 函数库下载 [Android 内存优化]图片文件压缩 ( Androi ...

  2. 【Android 内存优化】Android 原生 API 图片压缩原理 ( Bitmap_compress 方法解析 | Skia 二维图形库 | libjpeg 函数库 | libpng 函数库 )

    文章目录 一. 图片质量压缩方法 二. Skia 二维图形库 三. libjpeg.libpng 函数库引入 在博客 [Android 内存优化]图片文件压缩 ( Android 原生 API 提供的 ...

  3. 【Android 内存优化】Android 原生 API 图片压缩原理 ( 图片质量压缩方法 | 查找 Java 源码中的 native 方法对应的 C++ 源码 )

    文章目录 一. 图片质量压缩方法 二. 查找对应的 Native 方法源码 三. 分析 Bitmap.cpp 中动态注册 Native 方法 在博客 [Android 内存优化]图片文件压缩 ( An ...

  4. Bitmap图片压缩,大图加载防止OOM

    文章目录 前言 RGB介绍 图片占用内存的计算 读取位图尺寸和类型 内存中如果加载一张 `500*500` 的 `png` 高清图片.应该是占用多少的内存? 如果这个图片为本地资源图片,是否还是0.9 ...

  5. 传递Bitmap + 图片压缩处理 并保存 + 壁纸设置 总结

    原博客地址:http://blog.csdn.net/moubenmao_jun/article/details/20055189 ================================== ...

  6. Android调整Bitmap图片大小

    #Android调整Bitmap图片大小 /*** 调整图片大小* * @param bitmap* 源* @param dst_w* 输出宽度* @param dst_h* 输出高度* @retur ...

  7. 【Android 内存优化】Android 原生 API 图片压缩代码示例 ( PNG 格式压缩 | JPEG 格式压缩 | WEBP 格式压缩 | 动态权限申请 | Android10 存储策略 )

    文章目录 一. 图片质量压缩 二. 图片尺寸压缩 三. Android 10 文件访问 四. 完整源码示例 上一篇博客 [Android 内存优化]图片文件压缩 ( Android 原生 API 提供 ...

  8. Android BitMap图片压缩

    最近在网上看了一些关于图片压缩的博客,自己也动手实验了一遍,也算事对图片压缩有了一个了解,打算写个博客记录一下.文末附上参考链接. Android中涉及到图片的话一般都会用到BitMap类和Bitma ...

  9. Android 图片压缩、内存计算

    前言 再平时开发中肯定都会用到图片相关知识,而平时大多都只会关注实现方面,但一些理论对于面试和更深入高级实现就很有用,比如很多第三方组件很多都已经实现,本篇文章先从图片加载内存计算.图片压缩.图片另存 ...

最新文章

  1. 2022-2028年中国音像制品行业投资分析及前景预测报告
  2. Python基础编程——多重继承下方法的调用
  3. 前端性能优化之--页面渲染优化全面解析
  4. 【JavaScript 学习笔记】创建对象
  5. spring 整和activemq
  6. linux iptables扩展,脚本防火墙
  7. python模块搜索路径 (sys.path)
  8. Kali Linux下安装VMware
  9. 洛谷P2708题题解(Java语言描述)
  10. JS 函数中的call,apply
  11. pythondd_python学习笔记(五)之字典2-阿里云开发者社区
  12. 手持设备点击响应速度,鼠标事件与touch事件的那些事
  13. Linked List Cycle | ||
  14. 分享Swing学习的一些经验
  15. 控制面板中java设置项如何删除
  16. 富士胶片滤镜人像调色预设PS插件
  17. 关于DNF的多媒体包NPK文件的那些事儿(8) - DNF里的DDS图像
  18. 用差分法求解burger方程 matlab,偏微分方程数值解上机实验.doc
  19. python中的statistics_详解python statistics模块及函数用法
  20. 新能源与材料如何应用计算机,计算机模拟在光电材料及太阳能工程领域的应用与新进展.doc...

热门文章

  1. Try-with-resources are not supported at language level ‘5‘ 报错
  2. Python中的对象实例化过程 用python解密__new__
  3. 如何用cmd链接linux,如何在Windows cmd 下使用linux的命令
  4. Java 中ArrayList中的重复数据
  5. word表批量处理小技巧(python+宏)
  6. 手机如何实现边有线上网边充电?
  7. 从零开始的Wordpress个人网站搭建(图文)
  8. 现代函数概念的“序偶”定义
  9. Matlab中的c2d函数用法以及绘制传函的Bode图
  10. ubuntu中rar与unrar用法详解