详解Android Bitmap的常用压缩方式

一、前言

已经好久没有更新博客,大概有半年了,主要是博主这段时间忙于找工作,Android岗位的工作真的是越来越难找,好不容易在广州找到一家,主要做海外产品,公司研发实力也不错,所以就敲定了三方协议。现在已经在公司实习了一个月多,目前主要是负责公司某个产品的内存优化,刚好就总结了一下Android Bitmap常用的优化方式。

Android中的图片是以Bitmap方式存在的,绘制的时候也是Bitmap,直接影响到app运行时的内存,在Android,Bitmap所占用的内存计算公式是:图片长度 x 图片宽度 x像素点的字节数

二、图片常用的压缩格式

Enum Values
ALPHA_8 每个像素都存储为一个半透明(alpha)通道
ARGB_4444 此字段已在API级别13中弃用。由于此配置的质量较差,建议使用ARGB_8888
ARGB_8888 每个像素存储在4个字节。
RGB_565 每个像素存储在2个字节中,只有RGB通道被编码:红色以5位精度存储(32个可能值),绿色以6位精度存储(64个可能值),蓝色存储为5位精确。

其中字母代表的意思我们大概都可以理解,接下来我们来算算它们单个像素点的字节数:

  1. ALPHA_8:表示8位Alpha位图,即透明度占8个位,一个像素点占用1个字节,它没有颜色,只有透明度。
  2. ARGB_4444:表示16位ARGB位图,即A=4,R=4,G=4,B=4,一个像素点占4+4+4+4=16位,2个字节。
  3. ARGB_8888:表示32位ARGB位图,即A=8,R=8,G=8,B=8,一个像素点占8+8+8+8=32位,4个字节。
  4. RGB_565 :表示16位RGB位图,即R=5,G=6,B=5,它没有透明度,一个像素点占5+6+5=16位,2个字节

我们在做压缩处理的时候,可以先通过改变Bitmap的图片格式,来达到压缩的效果,其实压缩最主要就是要么改变其宽高,要么就通过减少其单个像素占用的内存。

三、常用的压缩方法:

1.质量压缩

  private void compressQuality() {
    Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.test);
    mSrcSize = bm.getByteCount() + "byte";
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    bm.compress(Bitmap.CompressFormat.JPEG, 100, bos);
    byte[] bytes = bos.toByteArray();
    mSrcBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
  }

质量压缩不会减少图片的像素,它是在保持像素的前提下改变图片的位深及透明度,来达到压缩图片的目的,图片的长,宽,像素都不会改变,那么bitmap所占内存大小是不会变的。

我们可以看到有个参数:quality,可以调节你压缩的比例,但是还要注意一点就是,质量压缩堆png格式这种图片没有作用,因为png是无损压缩。

2.采样率压缩

  private void compressSampling() {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 2;
    mSrcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test, options);
  }

采样率压缩其原理其实也是缩放bitamp的尺寸,通过调节其inSampleSize参数,比如调节为2,宽高会为原来的1/2,内存变回原来的1/4.

3.放缩法压缩

  private void compressMatrix() {
    Matrix matrix = new Matrix();
    matrix.setScale(0.5f, 0.5f);
    Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.test);
    mSrcBitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
    bm = null;
  }

放缩法压缩使用的是通过矩阵对图片进行裁剪,也是通过缩放图片尺寸,来达到压缩图片的效果,和采样率的原理一样。

4.RGB_565压缩

  private void compressRGB565() {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inPreferredConfig = Bitmap.Config.RGB_565;
    mSrcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test, options);
  }

这是通过压缩像素占用的内存来达到压缩的效果,一般不建议使用ARGB_4444,因为画质实在是辣鸡,如果对透明度没有要求,建议可以改成RGB_565,相比ARGB_8888将节省一半的内存开销。

5.createScaledBitmap

  private void compressScaleBitmap() {
    Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.test);
    mSrcBitmap = Bitmap.createScaledBitmap(bm, 600, 900, true);
    bm = null;
  }

将图片的大小压缩成用户的期望大小,来减少占用内存。

四、效果图

详解Android Bitmap的常用压缩方式

五、总结

以上5种就是我们常用的压缩方法了,这里的压缩也只是针对在运行加载的bitmap占用内存的大小。我们在做App内存优化的时候,一般可以从这两个方面入手,一个内存泄漏,另外一个是Bitmap压缩了,在要求像素不高的情况下,可以对Bitmap进行压缩,并且针对一些只使用一次的bitmap,要做好recycle的处理。

源码地址:https://github.com/codingma/BitmapCompress

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • 详解android 通过uri获取bitmap图片并压缩
  • Android Bitmap压缩方式分析
  • Android实现图片压缩(bitmap的六种压缩方式)
  • Android Bitmap压缩方法的选择详解
  • android bitmap compress(图片压缩)代码
时间: 2018-01-11

Android Bitmap压缩方法的选择详解

刚刚修改Bug碰到了一个问题,先描述一下问题. 1.测试说分享文章到微信失败,QQ成功. 定位到微信分享接口. 2.分享其它文章到微信成功. 接口有问题!差点就找接口了,还好没 3.断点微信分享,发现突然压缩失败. 代码写法问题,下面会分解 4.找到原因,微信对分享缩略图大小有32k的限制,代码是对文章的第一张图片进行压缩,图片太大,压缩代码也有问题. 开始解决问题 这里有两种解决方法: 1.接口提供文章对应的分享内容,在编辑人员编辑文章的时候就对这些数据进行了限制. { "title"

Android Bitmap压缩方式分析

Android Bitmap压缩方式分析 在网上调查了图片压缩的方法并实装后,大致上可以认为有两类压缩:质量压缩(不改变图片的尺寸)和尺寸压缩(相当于是像素上的压缩):质量压缩一般可用于上传大图前的处理,这样就可以节省一定的流量,毕竟现在的手机拍照都能达到3M左右了,尺寸压缩一般可用于生成缩略图. 在Android开发中我们都会遇到在一个100*100的ImageView上显示一张过大的图片,如果直接把这张图片显示上去对我们应用没有一点好处反而存在OOM的危险,所以我们有必要采用一种有效压缩方式

android bitmap compress(图片压缩)代码

android的照相功能随着手机硬件的发展,变得越来越强大,能够找出很高分辨率的图片.有些场景中,需要照相并且上传到服务,但是由于图片的大小太大,那么就上传就会很慢(在有些网络情况下),而且很耗流量,要想速度快,那么就需要减小图片的大小.减少图片的大小有两种方法,1. 照小图片: 2. 压缩大图片. 照相时获取小图片一般不太符合要求,因为,图片的清晰度会很差,但是这种情况有个好处就是应用速度会快些: 压缩图片,就是把大图片压缩小,降低图片的质量,在一定范围内,降低图片的大小,并且满足需求(图片仍

Android实现图片压缩(bitmap的六种压缩方式)

Android中图片是以bitmap形式存在的,那么bitmap所占内存,直接影响到了应用所占内存大小,首先要知道bitmap所占内存大小计算方式: 图片长度 x 图片宽度 x 一个像素点占用的字节数 以下是图片的压缩格式: 其中,A代表透明度:R代表红色:G代表绿色:B代表蓝色. ALPHA_8 表示8位Alpha位图,即A=8,一个像素点占用1个字节,它没有颜色,只有透明度 ARGB_4444 表示16位ARGB位图,即A=4,R=4,G=4,B=4,一个像素点占4+4+4+4=16位,2个

详解android 通过uri获取bitmap图片并压缩

详解android 通过uri获取bitmap图片并压缩 很多人在调用图库选择图片时会在onActivityResult中用Media.getBitmap来获取返回的图片,如下: Uri mImageCaptureUri = data.getData(); Bitmap photoBmp = null; if (mImageCaptureUri != null) { photoBmp = MediaStore.Images.Media.getBitmap(ac.getContentResolve

详解Android .9.png “点九”图片的使用

"点九"图片概述 "点九"是andriod平台的应用软件开发里的一种特殊的图片形式,文件扩展名为:.9.png. 我们都知道android平台有多种不同的分辨率,很多控件的切图文件在被放大拉伸后,边角会模糊失真,而使用点九PNG技术,可以将图片横向和纵向同时进行拉伸,以实现在多分辨率下的完美显示效果. 而且使用*.9.png图片技术,只需要采用一套界面切图去适配不同的分辨率,大幅减少安装包的大小.程序不需要专门做处理的就可以实现其拉伸,也减少了代码量和开发工作量.

详解Android中图片的三级缓存及实例

详解Android中图片的三级缓存及实例 为什么要使用三级缓存 如今的 Android App 经常会需要网络交互,通过网络获取图片是再正常不过的事了 假如每次启动的时候都从网络拉取图片的话,势必会消耗很多流量.在当前的状况下,对于非wifi用户来说,流量还是很贵的,一个很耗流量的应用,其用户数量级肯定要受到影响 特别是,当我们想要重复浏览一些图片时,如果每一次浏览都需要通过网络获取,流量的浪费可想而知 所以提出三级缓存策略,通过网络.本地.内存三级缓存图片,来减少不必要的网络交互,避免浪费流量

详解Android中获取软键盘状态和软键盘高度

详解Android中获取软键盘状态和软键盘高度 应用场景 在Android应用中有时会需要获取软键盘的状态(即软键盘是显示还是隐藏)和软键盘的高度.这里列举了一些可能的应用场景. 场景一 当软键盘显示时,按下返回键应当是收起软键盘,而不是回退到上一个界面,但部分机型在返回键处理上有bug,按下返回键后,虽然软键盘会自动收起,但不会消费返回事件,导致Activity还会收到这次返回事件,执行回退操作,这时就需要判断,如果软键盘刚刚由显示变为隐藏状态,就不执行回退操作. 场景二 当软键盘弹出后,会将

详解Android 中AsyncTask 的使用

详解Android 中AsyncTask 的使用 1.首先我们来看看AsyncTask 的介绍:   Handler 和 AsyncTask 都是android 中用来实现异步任务处理的方式:其中: Handler 实例向 UI 线程发送消息,完成界面更新, 优点:对整个过程控制的比较精细:         缺点:代码相对臃肿,多个任务同时执行时,不易对线程进行精确的控制: AsyncTask :比Handler 更轻量级一些,适用于简单的异步处理: 优点:简单 | 快捷 | 过程可控:    

详解Android中Intent对象与Intent Filter过滤匹配过程

如果对Intent不是特别了解,可以参见博文<详解Android中Intent的使用方法>,该文对本文要使用的action.category以及data都进行了详细介绍.如果想了解在开发中常见Intent的使用,可以参见<Android中Intent习惯用法>. 本文内容有点长,希望大家可以耐心读完. 本文在描述组件在manifest中注册的Intent Filter过滤器时,统一用intent-filter表示. 一.概述 我们知道,Intent是分两种的:显式Intent和隐式

详解Android获得系统GPU参数 gl.glGetString

详解Android获得系统GPU参数 gl.glGetString 通过文档的查找,以及源码的剖析,Android的GPU信息需要通过OpenGL来获取,android framework层提供GL10来获取相应的参数,而GL10要在使用自定义的View时才可以获得,下面是获得GPU信息的例子: 1.实现Render类 class DemoRenderer implements GLSurfaceView.Renderer { public void onSurfaceCreated(GL10

详解Android更改APP语言模式的实现过程

一.效果图 二.描述 更改Android项目中的语言,这个作用于只用于此APP,不会作用于整个系统 三.解决方案 (一)布局文件 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" a

详解 Android中Libgdx使用ShapeRenderer自定义Actor解决无法接收到Touch事件的问题

详解 Android中Libgdx使用ShapeRenderer自定义Actor解决无法接收到Touch事件的问题 今天在项目中实现了一个效果,主要是画一个圆.为了后续使用方便,将这个圆封装在一个自定义Actor(CircleActot)中,后续想显示一个圆的时候,只要创建一个CircleActor中即可. 部分代码如下所示: package com.ef.smallstar.unitmap.widget; import android.content.res.Resources; import

实例详解Android文件存储数据方式

总体的来讲,数据存储方式有三种:一个是文件,一个是数据库,另一个则是网络.下面通过本文给大家介绍Android文件存储数据方式. 1.文件存储数据使用了Java中的IO操作来进行文件的保存和读取,只不过Android在Context类中封装好了输入流和输出流的获取方法. 创建的存储文件保存在/data/data/<package name>/files文件夹下. 2.操作. 保存文件内容:通过Context.openFileOutput获取输出流,参数分别为文件名和存储模式. 读取文件内容:通