close
当前位置: 物联网在线 > 技术文库 > android >

Android开源 - Luban(鲁班)可能是最接近微信朋友圈的图片压缩算法

Luban 是图片压缩工具,通过参考或者自创压缩规则推求极致的压缩效果 目前的版本压缩效果主要参考微信。因为微信用户量最大,如果压缩后的图片越接近微信则越被用户接受。

说明

目前的 Luban 只是压缩结果接近微信,自身的算法只是为了达到这个效果而设计的。与微信并无任何联系,也不敢妄称是微信的算法。

算法步骤

注:下文所说“比例”统一表示:图片短边除以长边为该图片比例

第三挡压缩(参考最新版微信压缩效果)

判断图片比例值,是否处于以下区间内;

[1, 0.5625) 即图片处于 [1:1 ~ 9:16) 比例范围内

[0.5625, 0.5) 即图片处于 [9:16 ~ 1:2) 比例范围内

[0.5, 0) 即图片处于 [1:2 ~ 1:∞) 比例范围内

判断图片最长边是否过边界值;

[1, 0.5625) 边界值为:1664 * n(n=1), 4990 * n(n=2), 1280 * pow(2, n-1)(n≥3)

[0.5625, 0.5) 边界值为:1280 * pow(2, n-1)(n≥1)

[0.5, 0) 边界值为:1280 * pow(2, n-1)(n≥1)

计算压缩图片实际边长值,以第2步计算结果为准,超过某个边界值则:width / pow(2, n-1),height/pow(2, n-1)

计算压缩图片的实际文件大小,以第2、3步结果为准,图片比例越大则文件越大。

size = (newW * newH) / (width * height) * m;

[1, 0.5625) 则 width & height 对应 1664,4990,1280 * n(n≥3),m 对应 150,300,300;

[0.5625, 0.5) 则 width = 1440,height = 2560, m = 200;

[0.5, 0) 则 width = 1280,height = 1280 / scale,m = 500;注:scale为比例值

判断第4步的size是否过小

[1, 0.5625) 则最小 size 对应 60,60,100

[0.5625, 0.5) 则最小 size 都为 100

[0.5, 0) 则最小 size 都为 100

将前面求到的值压缩图片 width, height, size 传入压缩流程,压缩图片直到满足以上数值

效果与对比 内容 原图 Luban Wechat
截屏 720P   720*1280,390k   720*1280,87k   720*1280,56k  
截屏 1080P   1080*1920,2.21M   1080*1920,104k   1080*1920,112k  
拍照 13M(4:3)   3096*4128,3.12M   1548*2064,141k   1548*2064,147k  
拍照 9.6M(16:9)   4128*2322,4.64M   1032*581,97k   1032*581,74k  
滚动截屏   1080*6433,1.56M   1080*6433,351k   1080*6433,482k  
导入 compile 'io.reactivex:rxandroid:1.2.1' compile 'io.reactivex:rxjava:1.1.6' compile 'top.zibin:Luban:1.0.5' 使用 Listener方式

Luban内部采用io线程进行图片压缩,外部调用只需设置好结果监听即可

Luban.get(this) .load(File) //传人要压缩的图片 .putGear(Luban.THIRD_GEAR) //设定压缩档次,默认三挡 .setCompressListener(new OnCompressListener() { //设置回调 @Override public void onStart() { //TODO 压缩开始前调用,可以在方法内启动 loading UI } @Override public void onSuccess(File file) { //TODO 压缩成功后调用,返回压缩后的图片文件 } @Override public void onError(Throwable e) { //TODO 当压缩过去出现问题时调用 } }).launch(); //启动压缩 RxJava方式

RxJava 调用方式请自行随意控制线程

Luban.get(this) .load(file) .putGear(Luban.THIRD_GEAR) .asObservable() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnError(new Action1<Throwable>() { @Override public void call(Throwable throwable) { throwable.printStackTrace(); } }) .onErrorResumeNext(new Func1<Throwable, Observable<? extends File>>() { @Override public Observable<? extends File> call(Throwable throwable) { return Observable.empty(); } }) .subscribe(new Action1<File>() { @Override public void call(File file) { //TODO 压缩成功后调用,返回压缩后的图片文件 } });
(责任编辑:ioter)

用户喜欢...

Android Weekly #276 安卓开发周刊 中文版

您是否了解过Android的Lifecycle-Aware库?(android.jlelse.eu) 我们如何了解Lifecycle-Aware库代码? Nishant Srivastava展示了可以跟踪活动或Lifecycle-Aware的Lifecycle Arch组件的片段,并相应地调整其行为。 为Mos...


Android Weekly #275 安卓开发周刊 中文版

MapMe — Android地图适配器 (medium.com) Josh Burton介绍MapMe,是一个用Kotlin编写的Android库,可以将适配器模式带到地图上。 赞助 CloudRail - 连接到API 10x更快 (cloudrail.com) 当我们用单一的界面连接到所...


使用Android Studio开发可独立运行(runnable)混淆过的Jar程序

之前开发Java程序一直都是使用Eclipse 开发Jar程序,现在开发基本上都已经弃用Eclipse了,但是有时偶尔开发个小的Jar程序,还要切换回去好麻烦,刚好前几天有人问几个相关的问题,就顺便整...


Android Weekly #274 安卓开发周刊 中文版

探索Android Oreo上的别后执行限制(medium.com) 在这篇文章中,Joe Birch解释了关于Android Oreo在后台运行服务的变化。 non-Time领主的time – 第5部分 (blog.stylingandroid.com) Mark Allison继续分析JSR 310 date和...


Android Weekly #273 安卓开发周刊 中文版

开源你的Android代码(android.jlelse.eu) 通过您的开源Android代码,您将(希望地)为Android社区提供有价值的代码,收到建设性的反馈,并与您最初建立的内容进行协作从而使您的代码变得更好。这...


Android Weekly #272 安卓开发周刊 中文版

Android Dev 101:每个初学者都应该知道的一些做法() 看一些初学者或媒介等级开发人员(不要错过任何人)应该知道的一些做法,以便更好地摆脱Android框架。 99.9% crash free sessions (medium.com) Chr...


Android Weekly #271 安卓开发周刊 中文版

依赖注入检查(medium.com) 在本文中,MihályNagy引入了依赖注入检查,一种开源注释处理器,可帮助您解决一些出现在所有JSR 330 DI库中常见的问题。 使用Android Studio插件提高效率 (blog.mindorks.com...


Android Weekly #270 安卓开发周刊 中文版

带有RxJava2的SOLID Android分析 (medium.com) 在这篇文章中,Aris Papadopoulos将解释如何正确创建一个分析系统,同时遵循SOLID原则,并使用RxJava2来解决问题。 (blog.stylingandroid.com) Java中的编程时间很难...


Android内存泄漏思考

Android内存泄漏是一个经常要遇到的问题,程序在内存泄漏的时候很容易导致OOM的发生。那么如何查找内存泄漏和避免内存泄漏就是需要知晓的一个问题,首先我们需要知道一些基础知识。...


Android Weekly #269 安卓开发周刊 中文版

在Google上快速提出操作 () Wolfram Rittmeyer分享了开始在Google上快速创建操作所需的所有信息(为了家庭与助理)。 RxJava中的错误处理(rongi.github.io) 一旦开始编写RxJava代码,你就会意识到有些事...