Android-图片压缩(二)-纯干货
前言:让我们手撸一个图片压缩库,对压缩工具鲁班进行升级改造。
在平常开发当中,我们一般是使用第三方的工具,不仅快,而且上手简单,基本不用我们动脑子,压缩我们用鲁班压缩,加载图片我们用Glide,这两大工具我想在座的基本上都用吧,不过我们要想提升自己,就要搞清楚深一点的东西,这里我将会带着大家做一款压缩工具,功能媲美鲁班压缩,而且还带有鲁班没有的功能,如输出指定格式等,在这个过程中我们要学会如何获取bitmap,第一篇已经罗列了多种从项目中取图片转bitmap,这里就不多说了。当我们拿到bitmap我们要知道的事情还有很多,比如图片的色彩模式,一个像素点大小,什么是色深,位深等。绝对让你有收获,干货满满,冲呀。
1、图片相关概念
1.1 ARGB介绍
1.2 Bitmap概念
1.3 色彩模式
- ALPHA_8 =>8位(1B)
- RGB_565 =>16位(2B)
- ARGB_4444 =>16位(2B)
- ARGB_8888 =>32比特位(4字节,4B)
- RGBA_F16 =>64位(8B)
注意:1 byte(字节) = 8bit(位)1 KB = 1024 byte(字节)
1.4 色深和位深
- 色深:每一个像素点用多少bit来存储ARGB值
- 位深:每个像素点在计算机中所使用的二进制数值位数叫做位深度,主要用于存储
1.5 内存中Bitmap的大小
1.6 系统一般分配的大小
// 获取应用程序最大可用内存(以字节为单位,/1024/1024=M 华为p20 pro是384M)
int maxMemory = (int) Runtime.getRuntime().maxMemory();
int cacheSize = maxMemory / 8;
// 设置图片缓存大小为程序最大可用内存的1/8
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getByteCount();
}
----------------------其他获取方式--------------------
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
//最大分配内存,单位M
int memoryClass = activityManager.getMemoryClass();
Log.e("memoryclass=",String.valueOf(memoryClass));
//最大分配内存获取方法2
float maxMemory = (float) (Runtime.getRuntime().maxMemory() * 1.0/ (1024 * 1024));
//当前分配的总内存
float totalMemory = (float) (Runtime.getRuntime().totalMemory() * 1.0/ (1024 * 1024));
//剩余内存
float freeMemory = (float) (Runtime.getRuntime().freeMemory() * 1.0/ (1024 * 1024));
Log.e("memoryclass=maxMemory",String.valueOf(maxMemory));
Log.e("memoryclass=totalMemory",String.valueOf(totalMemory));
Log.e("memoryclass=freeMemory",String.valueOf(freeMemory));
2、图片压缩方式
- 设置图片格式
- png:无损的压缩图片格式
- jpeg:有损的压缩图片格式,不能透明设置。
- webp:同时提供了有损和无损图片格式。无损的格式要比png小26%,有损的比jpeg大25%-30%。
- 质量压缩
- 采样率压缩
- 缩放压缩
- 减少图片的像素,缩略图
- JNI调用JPEG库
Android目前常用的图片格式有png,jpeg和webp,
png:无损压缩图片格式,支持Alpha通道,Android切图素材多采用此格式jpeg:有损压缩图片格式,不支持背景透明,适用于照片等色彩丰富的大图压缩,不适合logowebp:是一种同时提供了有损压缩和无损压缩的图片格式,派生自视频编码格式VP8,从谷歌官网来看,无损webp平均比png小26%,有损的webp平均比jpeg小25%~34%,无损webp支持Alpha通道,有损webp在一定的条件下同样支持,有损webp在Android4.0(API 14)之后支持,无损和透明在Android4.3(API18)之后支持采用webp能够在保持图片清晰度的情况下,可以有效减小图片所占有的磁盘空间大小
Android中Bitmap所占内存大小计算方式:图片长度 x 图片宽度 x 一个像素点占用的字节数
3、压缩的常见方式
- 质量压缩:降低存储体积(不改变内存中Bitmap的大小)
- 采样压缩:降低图片的尺寸,(当然存储体积和内存占用都会降低)
质量压缩:主要是通过编解码来达到缩小体积。采样压缩:主要是通过采样率,像素点个数等来达到缩小体积
3.1、质量压缩
Bitmap.compress(Bitmap.CompressFormat.JPEG,quality,outputStream)
其中
Bitmap.CompressFormat.JPEG
Bitmap.CompressFormat.PNG 无损,无法再质量压缩?
Bitmap.CompressFormat.WEBP 可优化30%,比JPEG更加省空间
quality:0-100,1最小体积,100 最高质量,体积也是最大
outputStream: ByteArrayOutputStream 一个输出流,压缩后的流,如果要保存成图片文件,就保存此流
3.2、采样压缩
- 临近采样(临近点插值算法)
- 双线性采样(双线性内插值算法)
3.2.1 临近采样(临近点插值算法)
使用了BitmapFactory.options 下的
inSampleSize:采样压缩系数 如果是2,直接缩放宽高为原先 二分之一 (1/2)
该方式比较粗暴,2个像素取一个。宽高都减少了,自然内存也降低了。
------------------------------------------------------------------------------
public static void ljCom(InputStream open){
BitmapFactory.Options options = new BitmapFactory.Options();
//或者 inDensity 搭配 inTargetDensity 使用,算法和 inSampleSize 一样
options.inSampleSize = 2; //设置图片的缩放比例(宽和高) , google推荐用2的倍数:
// Bitmap bitmap = BitmapFactory.decodeFile("app/src/main/assets/wx.png");
// Bitmap compress = BitmapFactory.decodeFile("app/src/main/assets/wx.png", options);
Bitmap mbitmap = BitmapFactory.decodeStream(open, null, options);
Log.e("双线性采样","----压缩后----》"
+"\n内存大小》"+mbitmap.getByteCount()
+"\n宽度》"+mbitmap.getWidth()
+"\n高度》"+mbitmap.getHeight());
}
3.2.2 双线性采样(双线性内插值算法)
Bitmap bitmap = BitmapFactory.decodeFile("xxx.png");
Bitmap compress = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth()/2, bitmap.getHeight()/2, true);
或者直接使用 matrix 进行缩放
Bitmap bitmap = BitmapFactory.decodeFile("xxx.png");
Matrix matrix = new Matrix();
matrix.setScale(0.5f, 0.5f);
bm = Bitmap.createBitmap(bitmap, 0, 0, bit.getWidth(), bit.getHeight(), matrix, true);
filter:当进行的不只是平移变换时,filter参数为true可以进行滤波处理,有助于改善新图像质量;flase时,计算机不做过滤处理。
/**
* 双线性采样
* */
public static void sxxCon(Bitmap bitmap){
Log.e("双线性采样","----压缩前----》"
+"\n内存大小》"+bitmap.getByteCount()
+"\n原图宽度》"+bitmap.getWidth()
+"\n原图高度》"+bitmap.getHeight());
//等比例缩放压缩
Bitmap mbitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth()/2, bitmap.getHeight()/2, true);
Log.e("双线性采样","----压缩后----》"
+"\n内存大小》"+mbitmap.getByteCount()
+"\n宽度》"+mbitmap.getWidth()
+"\n高度》"+mbitmap.getHeight());
}
/**
* 双线性采样
* */
public static void sxxCon2(Context context,Bitmap bitmap){
Log.e("双线性采样","----压缩前----》"
+"\n内存大小》"+bitmap.getByteCount()
+"\n宽度》"+bitmap.getWidth()
+"\n高度》"+bitmap.getHeight());
Matrix matrix = new Matrix();
matrix.setScale(0.6f, 0.6f);
Bitmap mbitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
Log.e("双线性采样","----压缩后----》\n"
+"\n内存大小》"+mbitmap.getByteCount()
+"\n宽度》"+mbitmap.getWidth()
+"\n高度》"+mbitmap.getHeight());
saveBitmapAsPng2(context,mbitmap,"aaq");
}
3.2.3 双线性采样对比邻近采样的优势在于:
4、微信和鲁班压缩对比
|
微信
|
LuBan
|
|
|
1
|
采样率压缩
|
|
|
2
|
进行宽高的等比压缩(微信对原图和缩略图限制了最大长宽或者最小长宽)
|
进行宽高的等比压缩
|
|
3
|
对图片的质量进行压缩(一般75或者70)
应该说的是quality=75
|
对图片的质量进行压缩
|
|
4
|
采用webP的格式
|
Android-图片压缩(二)-纯干货的更多相关文章
- Android图片压缩上传(二)
之前有用到libjpeg,还是有一定的局限性,最近用了一个新的方式,效果还是挺不错,随着作者的版本更新,Bug也随之变少,目前项目中运用已上线. 1.之前的方式Android图片压缩,不失真,上线项目 ...
- android图片压缩方法
android 图片压缩方法: 第一:质量压缩法: private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = ...
- android图片压缩的3种方法实例
android 图片压缩方法: 第一:质量压缩法: private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = ...
- Android 图片压缩器
概述 Android 图片压缩器:一款高效的图片压缩器库,支持批量压缩,异步压缩.多线程多任务压缩,压缩比设置等特性. 详细 代码下载:http://www.demodashi.com/demo/12 ...
- Android 图片压缩各种方式
前言:由于公司项目当中需要用到压缩这块的相应技术,之前也做过的图片压缩都不是特别的理想, 所以这次花了很多心思,仔细研究和在网上找到了很多相对应的资料.为了就是 以后再做的时候直接拿来用就可以了 ...
- Android 图片压缩、照片选择、裁剪,上传、一整套图片解决方案
1.Android一整套图片解决方案 http://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650820998&idx=1& ...
- android图片压缩总结
一.bitmap 图片格式介绍 android中图片是以bitmap形式存在的,那么bitmap所占内存,直接影响到了应用所占内存大小,首先要知道bitmap所占内存大小计算方式: bitmap内存大 ...
- Android图片压缩方法总结
本文总结Android应用开发中三种常见的图片压缩方法,分别是:质量压缩法.比例压缩法(根据路径获取图片并压缩)和比例压缩法(根据Bitmap图片压缩). 第一:质量压缩方法: ? 1 2 3 ...
- Android图片压缩
import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java ...
- 性能优化——Android图片压缩与优化的几种方式
图片优化压缩方式大概可以分为以下几类:更换图片格式,质量压缩,采样率压缩,缩放压缩,调用jpeg压缩等1.设置图片格式Android目前常用的图片格式有png,jpeg和webp,png:无损压缩图片 ...
随机推荐
- 微信小程序按下去的样式
微信小程序设置 hover-class,实现点击态效果 目前支持 hover-class 属性的组件有三个:view.button.navigator. 不支持 hover-class 属性的组件,同 ...
- svn操作方法
1.SVN1.1.SVN概述1.1.1.为什么需要使用svn版本控制软件协作开发远程开发版本回退 1.1.2.解决之道SCM:软件配置管理所谓的软件配置管理实际就是对软件源代码进行控制与管理. CVS ...
- windows2012通过powershell安装远程组件技巧
概要: 通过服务器管理器安装远程桌面服务会报错一直没有办法解决 之后了解到安装组件可以通过powershell命令安装 powershell命令说明 https://docs.microsoft. ...
- java8利用流和lambda表达式对list遍历处理
java8的lambda表达式提供了一些方便list操作的方法,主要涵盖分组.过滤.求和.最值.排序.去重. 优点: (1) 简洁,跟之前的传统写法对比,能少写不少代码; (2) 易并行计算.尤其适用 ...
- Maven项目的创建教程
1.创建Maven项目 首先File->New新建一个Maven项目,选择相应地址保存,点击CREATE完成新建 2.改成Web项目 右键选择Add Framework Support... 再 ...
- Android笔记--图像显示
imageView 具体实现: 注意:图片名称应当为小写的英文字母与数字的结合,当然,二者可以只存在其一 图片的放置的比例:(通过scaleType属性设置) ImageButton ImageBut ...
- 集训第二周计划:把cf近期的div2除了最后一题给切完
太菜了太菜了,弄个训练计划. 晚上没事干的时候我想把博客园皮肤改一下,搜着搜着不知道怎么回事点进去一些竞赛选手的博客,比如这个 https://www.cnblogs.com/soda-ma/p/13 ...
- Golang 实现 RTP
在 Coding 之前我们先来简单介绍一下 RTP(Real-time Transport Protocol), 正如它的名字所说,用于互联网的实时传输协议,通过 IP 网络传输音频和视频的网络协议. ...
- scrcpy软件的使用
一.scrcpy软件介绍: scrcpy是通过adb调试的方式来将手机屏幕投到电脑上,并可以通过电脑控制您的Android设备.它可以通过USB连接,也可以通过Wifi连接(类似于隔空投屏),而且不需 ...
- Hugging News #0317: ChatGLM 会成为 HF 趋势榜的第一名吗?
每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...