您的位置 首页 java

可能是最接近还原微信朋友圈的图片压缩算法

Luban

Android图片压缩工具,还原微信朋友圈压缩策略。

项目描述

目前做App开发总绕不开图片这个元素。但是随着手机拍照分辨率的提升,图片的压缩成为一个很重要的问题。单纯对图片进行裁切,压缩已经有很多文章介绍。但是裁切成多少,压缩成多少却很难控制好,裁切过头图片太小,质量压缩过头则显示效果太差。

于是自然想到App巨头“微信”会是怎么处理,Luban(鲁班)就是通过在微信朋友圈发送近100张不同分辨率图片,对比原图与微信压缩后的图片逆向推算出来的压缩算法。

因为有其他语言也想要实现Luban,所以描述了一遍算法步骤。

因为是逆向推算,效果还没法跟微信一模一样,但是已经很接近微信朋友圈压缩后的效果,具体看以下对比!

效果与对比

算法步骤

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

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

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

  • [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)

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

4.计算压缩图片的实际文件大小,以第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为比例值

5.判断第4步的size是否过小

  • [1, 0.5625) 则最小 size 对应 60,60,100
  • [0.5625, 0.5) 则最小 size 都为 100
  • [0.5, 0) 则最小 size 都为 100

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

导入

implementation 'top.zibin:Luban:1.1.8'
 

方法列表

异步调用

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

Luban.with(this)
 .load(photos)
 .ignoreBy(100)
 .setTargetDir(getPath())
 .filter(new CompressionPredicate() {
 @ Override 
 public boolean apply(String path) {
 return !(TextUtils. isEmpty (path) || path.toLowerCase().endsWith(".gif"));
 }
 })
 .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调用为例

Flowable.just(photos)
 .observeOn(Schedulers.io())
 .map(new Function<List<String>, List<File>>() {
 @Override public List<File> apply(@NonNull List<String> list) throws Exception {
 // 同步方法直接返回压缩后的文件
 return Luban.with(MainActivity.this).load(list).get();
 }
 })
 .observeOn(AndroidSchedulers.mainThread())
 .subscribe();
 

您知道哪些好用的图片算法,欢迎评论分享,共同探讨学习

如果觉得文章能够对您有所帮助,可以关注我,你的支持会鼓励我不断分享更多更好的优质文章。

文章来源:智云一二三科技

文章标题:可能是最接近还原微信朋友圈的图片压缩算法

文章地址:https://www.zhihuclub.com/185512.shtml

关于作者: 智云科技

热门文章

网站地图