大家都知道,android 应用在创建进程时候,会分配一个指定的内存大小,准确的说话是 google原生OS的默认值是16M,如果我们应用“毫不吝啬”将这些大图直接加载到内存中,很快内存就会耗尽,最终出现OOM异常,所以图片的处理对于一个稳定、用户体验友好的应用来说非常重要,在开发过程中把”图片“给优化一番,保证我们项目在线上稳定、流畅运行。

1.什么是Bitmap

bitmap在sdk中算是元老级的人物了,从api1中就已经有了,可见其重要性。继承关系就不解释了,实现了Parcelable 具备在内存中传递的特性。

bitmap中有两个重要的内部类 CompressFormat 以及 Config;

下面分别介绍一下这两个类

  • CompressFormat

CompressFormat 是用来设置压缩方式的,是个枚举类,内部提供了三种图片压缩方式类型,

  1. JPEG :表示Bitmap采用JPEG压缩算法进行压缩,压缩后的格式可以是.jpg或者.png,是一种有损压缩方式。

  2. PNG : 表示Bitmap采用PNG压缩算法进行压缩,压缩后的格式可以是.png,是一种无损压缩方式。

  3. WEBP :表示以WebP压缩算法进行图像压缩,压缩后的格式可以是".webp",是一种有损压缩,质量相同的情况下,WebP格式图像的体积要比JPEG格式图像小40%,美中不足的是,WebP格式图像的编码时间“比JPEG格式图像长8倍”, 而且还需要注意,在官方文档中有这样的描述:As of Build.VERSION_CODES.Q, a value of 100 results in a file in the lossless WEBP format. Otherwise the file will be in the lossy WEBP format. 意为Android10之后如果quality值(压缩质量)为100的话,bitmap压缩采用无损压缩格式,其他都为有损压缩;

这里有的同志会问,这都是压缩格式啊,具体怎么操作压缩呢,Bitmap为我们提供了一个可靠的方法供开发者使用,我们来顺便看看Bitmap都有什么方法,如下:

第一个方法就是compress()方法, 没错就是这么就这方法,一共有三个参数

  1. format :上面已经说明了,表示压缩格式;

  2. quality :压缩质量,取值0-100,0表示最低画质压缩,100表示最高画质压缩,对于PNG压缩格式来说,该参数可以忽略,对于WEBP格式来说,小于100为有损压缩格式,会对画质产生直接影响, 等于100时候采用的是无损压缩格式,画质是不会有改变,但是图片大小得到很好压缩;

  3. stream :将压缩后的图片写到指定的输出流中;

返回值:boolean, 返回true表示成功将bitmap压缩到输出流中,然后可以通过Bitmap.Factory从相应的输入流中解析出来bitmap信息;

从官网介绍可知, 该方法在图片压缩过程中可能消耗较长时间,建议放在子线程中操作,至于为什么大家可以看看源码, 源码中会调用一个nativeCompress 的Native 方法,也就是压缩处理是放在底层处理的;

  • Config

表示位图像素的存储格式,什么意思呢?  就是bitmap在屏幕上显示的每一像素在内存中存储的格式,会影响Bitmap真实图片的透明度以及图片质量;

  1. Bitmap.Config.ALPHA_8:颜色信息只由透明度组成,占8位;

  2. Bitmap.Config.ARGB_4444:颜色信息由透明度与R(Red),G(Green),B(Blue)四部分组成,每个部分都占4位,总共占16位;

  3. Bitmap.Config.ARGB_8888:颜色信息由透明度与R(Red),G(Green),B(Blue)四部分组成,每个部分都占8位,总共占32位,是Bitmap 默认的颜色存储格式,也是最占空间的一种配置;

  4. Bitmap.Config.RGB_565:颜色信息由R(Red),G(Green),B(Blue)三部分组成,R占5位,G占6位,B占5位,总共占16位;

上面说了 android 系统默认存储位图方式是 ARGB_8888, 4个通道组成,每个通道8位,分表代表透明度和RGB颜色值, 也就是说一个位图像素占用了4个字节(1个byte8个bit位),

同理:采用 Bitmap.Config.RGB_565 存储,单像素占用内存大小仅有2byte,换句话说一张图片采用ARGB_565格式相对于默认的ARGB_8888内存将减少一半,所以通过改变bitmap像素存储方式也是图片内存优化的重要渠道,这个后面会讲到;

bitmap是android中重要的图像处理工具类,通过bitmap可以对图像进行剪切、旋转、缩放等操作,同时还可以指定格式和压缩质量保存图像文件。


一、拿到一个Bitmap对象


查看源码我们知道,Bitmap被final修饰,因此不可以通过new来获得一个bitmap的实例,获得一个Bitmap对象一般都是通过BitmapFactory来获得,主要有以下几方式。

每一个方法都有自己的重载方法,重载方法多出的参数是Options,解释一下这个参数,这个主要是对生成Bitmap对象做一些简单的处理。

  1. inPreferredConfig 指定decode到内存中,手机中所采用的编码,可选值定义在Bitmap.Config中。缺省值是ARGB_8888。

  2. inJustDecodeBounds 如果设置为true,并不会把图像的数据完全解码,亦即decodeXyz()返回值为null,但是Options的outAbc中解出了图像的基本信息。

  3. inSampleSize 设置decode时的缩放比例。当值大于1时会对图像进行压缩,比如设置为4时,返回的图像宽高都将是原始图像的四分之一,像素是原始图像的十六分之一,如果设置的值小于1,则会被当作1来处理。注意,这里设值必须是2的次幂,其他值会被就近取离2的次幂最近的值。

通过option的这些属性,我们就可以获得一张图片的缩略图啦,一个基本思路是先设置inJustDecodeBounds为true,拿到图像的基本信息,比如宽和高,根据基本信息结合缩略图目标宽高,算出inSampleSize ,然后再设置inJustDecodeBounds为false,获得缩略图。

想要获得一个Bitmap对象,可以通过一个图像的完整路径,或者是通过一个字节流或者是通过字节亦或者是通过本地的资源文件,都可以获得一个Bitmap对象。

if (Environment.getExternalStorageState().equals(
                    Environment.MEDIA_MOUNTED)) {
                // /storage/emulated/0/DCIM/Camera/123.jpg
                String path = Environment.getExternalStorageDirectory()
                        .getAbsolutePath()
                        + File.separator
                        + "DCIM"
                        + File.separator
                        + "Camera"
                        + File.separator
                        + "123.jpg";
                BitmapFactory.Options option = new BitmapFactory.Options();
                option.inSampleSize = 1;
                //通过完整路径获得Bitmap对象
                Bitmap bm = BitmapFactory.decodeFile(path,option);
                FileInputStream is = new FileInputStream(new File(path));
                //通过一个输入流获得Bitmap对象
                Bitmap bm2 = BitmapFactory.decodeStream(is);
                //通过本地资源获得一个Bitmap对象
                Bitmap bm1 = BitmapFactory.decodeResource(getResources(),
                        R.drawable.ic_launcher);
                iv.setImageBitmap(bm2);
            }


二,保存图像文件


拿到了Bitmap之后可以直接显示出来,也可以先保存到本地等待处理,Bitmap可以保存为jpg,png,gif等格式,保存方式也是非常简单:

Bitmap bp = revitionImageSize(path + "123.jpg");FileOutputStream out = new FileOutputStream(path + "456.gif");//0意味着压缩到最小,100意味着压缩后的质量最好,PNG是无损图像,会忽略这个参数
//              bp.compress(Bitmap.CompressFormat.JPEG, 100, out);bp.compress(Bitmap.CompressFormat.PNG, 0, out);out.flush();out.close();

直接调用compress方法,第一个参数表示压缩的方式,有多种,PNG属于无损压缩,JPEG是有损压缩。第二个参数表示压缩质量,取值为0-100,100表示压缩图像质量最高,但同时压缩率低,0表示压缩图像质量最差,同时压缩率高。但是,这个参数是否有效与第一个参数有关,如果第一个参数选择了PNG,及无损压缩,那么第二参数是无效的。第三个参数是你要输出的字节流。

ZUI易入门Android之Bitmap(一)相关推荐

  1. ZUI易入门Android之客户端适配9.0方案

    目录 Section 1: 前言 1-4 1 概念 1-4 2 读者 1-4 3 参考文档 1-4 Section 2: 技术方案 2-5 1 所有应用的行为变更 2-5 1.1 非SDK开放接口 2 ...

  2. ZUI易入门Android之Okhttp的相关概念

    什么是okhttp? okhttp是一个第三方类库,用于android中请求网络.这是一个开源项目,是安卓端最火热的轻量级框架,由移动支付Square公司贡献(该公司还贡献了Picasso和LeakC ...

  3. ZUI易入门Android之开源框架的使用

    前言: 为了扩展大家的知识面,工作后对当前流行的一些开源框架有所了解,今天我们会给大家介绍一系列的第三方框架的使用方法.这些框架有的能简化我们的代码,比如那些繁冗的findviewbyid操作,有的把 ...

  4. ZUI易入门Android之JobScheduler

    在一篇关于网络优化的博文中发现了这个词.我们的项目中并没有使用到这个东西,但看了一下还是非常好用的,mark一下以后一定会用到吧. 贴官方文档,喜欢自学的可以过去看看 贴官方Demo,官方给出的例子也 ...

  5. ZUI易入门Android之Git的使用(一)本地仓库

    git的功能是很强大的,既可以做"本地仓库",也可以在"远程仓库"进行管理. git的基本使用如下 1.git init (初始化本地仓库) 2.git sta ...

  6. ZUI易入门Android之SQL 语句大全

    一.基础 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server ---  ...

  7. ZUI易入门前端 二、Javascript

    Html是描述页面内容的.CSS是让页面好看的,而JavaScript是让页面能够交互的.我们做网站的时候要实现"点击按钮之后图片切换"."鼠标放到图片上显示放大图&qu ...

  8. android.graphics.bitmap jar,Android入门之画图详解

    前文常用的控件介绍了不少,现在就来讨论一下手机开发中常用到的画图.要掌握Android的画图,首先就要了解一下,基本用到的如下一些图形接口: 1.Bitmap,可以来自资源/文件,也可以在程序中创建, ...

  9. 苏宁易购Android架构演进史

    http://www.infoq.com/cn/articles/suning-android-architecture 摘要 一个电商类APP,对用户而言,是琳琅满目的商品,是层出不穷的优惠,既是社 ...

最新文章

  1. 基于 Web 的 Linux 终端 WebTerminal
  2. QQ WINDWOS 8 METRO版使用体验
  3. Laravel中一些要记住 的写法
  4. php安卓交互安全,php结合安卓客户端实现查询交互实例
  5. AWS elastic load balancer里的监听器certificate设置
  6. 大厂技术文档:Python 基础+爬虫+数据分析+面试经精选
  7. reconnecting-websocket.min.js
  8. 计算机创新发展战略,计算机行业投资机会报告:智能汽车创新发展战略发布
  9. python视频教程推荐it教程网_Python系列视频教程集合【共119套】
  10. 基于javaweb+jsp的户籍管理系统(JavaWeb MySQL JSP Bootstrap Servlet SSM SpringBoot)
  11. 做饭给自己一人吃,如何最快速,且营养有保证?
  12. 腾讯下载的视频怎么转换成mp4格式
  13. 对d3d9里面的函数挂钩实现透视
  14. 【六月英语——空空的】
  15. “易+”开源 | 简单可信赖,GameSentry 正式开源
  16. PHP 8.1.0-dev后门复现
  17. CentOS Linux 内核升级
  18. XenServer Tools
  19. 图像区分平坦区域、边缘、角点区域
  20. bzoj1349 [Baltic2006]Squint

热门文章

  1. Maven学习笔记 (颜群老师讲解)
  2. @SentinelResource详解
  3. 数学建模(数据分析C题)-建模思路
  4. 递归(五):递归图形
  5. 记一次计通项目(网元设计)(更新中)
  6. 基于jacoco插件,使用python脚本分析java项目测试覆盖率。
  7. 富士胶片LTO磁带减排效益获认可;耀世星辉深度测试海外版语音社交产品“悦聊”CheerChat | 全球TMT...
  8. 专题总纲目录 管理类联考 MBA/MEM/MPA/MPACC总纲
  9. Java包括jvm及API,Java基础(下)(JVM、API)
  10. mysql timestamp 比较_解析mysql TIMESTAMP(时间戳)和datetime不同之处比较