Luban压缩源码学习

1.Android图片显示遇到的问题

在Android应用中加载图片,是一个需要消耗内存的一个动作。也是Android开发者在项目优化中比较头疼的一个问题。

先了解下加载图片如何消耗内存的

图片质量1px所占空间(1byte=8位)1024*1024图片大小
ALPHA_8只有透明度,没有颜色,那么一个像素点占8位。1byte1M
RGB_565 即R=5,G=6,B=5,没有透明度,那么一个像素点占5+6+5=16位2byte2M
ARGB_8888由4个8位组成,即A=8,R=8,G=8,B=8,那么一个像素点占8+8+8+8=32位4byte4M
ARGB_4444由4个4位组成,即A=4,R=4,G=4,B=4,那么一个像素点占4+4+4+4=16位2byte2M



而Android系统分配给单个应用的内存空间还是很有限的大致有16M,64M,128M等。如果一个应用加载大量高质量的图片的话就会导致一种情况出现——OOM(内存溢出)。

所以为了避免这种情况出现,就要对图片进行压缩处理显示。

对图片压缩处理就是进行裁切以及压缩,但是为了保证处理后的图片尽量达到跟原图效果一致,对图片裁切,压缩的一个度是如何控制呢。

这里介绍下一个第三方开源库——Luabn(最接近微信朋友圈压缩图片算法)

2.使用Luban压缩图片效果

上面两图中的上部分图片是原图,下面部分是经过Luban压缩过后的图片

效果:

第一张原图4.55m 尺寸3456x4608。 压缩过后53k 尺寸1152x1536

第二张原图1.16m 尺寸1080x1920。 压缩过后150k 尺寸360x640

我们可以发现压缩后的图片在不放大的情况下,图片效果和原图一致,Luban的处理效果特别好。

如何使用Luban压缩图片

1.在项目中的build.gradle添加依赖(需要用到RxJava1.0)
这里写图片描述

2.在代码中使用Luban压缩方法

1)Listerner方式。传入图片File,调用设置压缩监听setCompressListerner方法,处理压缩结果。
这里写图片描述

2)Rxjava方式,传入图片File,调用asObservable方法返回一个Observable观察者对象,使用RxJava方式来处理压缩结果。
这里写图片描述

项目地址

3.Luban源码分析

源码中最主要的方法就是thirdCompress(File file),即如何计算得出理想的压缩后宽高,以及图片大小。

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 传入压缩流程,压缩图片直到满足以上数值

源码:

根据算法计算压缩后的宽高以及图片文件大小,在调用压缩方法compress,传入计算后的宽高以及图片大小

开始进行压缩,这里分别执行了压缩图片大小compress方法,以及压缩图片质量saveImage方法
这里写图片描述

压缩图片至预期大小,配置BitmapFactory.Options中inSampleSize的值来压缩图片的宽高

图片质量压缩
这里写图片描述

4.主要代码分析

清楚了第三档压缩的实现之后,再了解使用Luban压缩时用到几个方法:

get()、load(file)、putGear() 、setFileName()、setCompressListener()、launch()、asObservable()

get(Context context)

这里写图片描述

这里写图片描述

首先调用的是get(this),传入的是一个Context对象,调用私有的构造方法传入一个File对象创建一个Luban对象;File对象生成调用的是getPhotoCacheDir方法,来指定缓存目录。

路径为:app包名/cache/luban_disk_cache/文件名

这里写图片描述

load(File file)

public Luban load(File file) {mFile = file;return this;
}

这个方法比较容易理解,传入的是我们图片文件。

putGear(int gear)

public Luban putGear(int gear) {this.gear = gear;return this;
}

设置压缩等级,源码中只有两种等级:FIRST_GEAR 和 THIRD_GEAR,传入其他值无效。

    private static final int FIRST_GEAR = 1;public static final int THIRD_GEAR = 3;

setFileName(String fileName)

设置压缩后的图片名称

    public Luban setFilename(String filename) {this.filename = filename;return this;}

setCompressListener(OnCompressListener listener)

设置压缩监听 OnCompressListener是一个接口,里面有三个方法,对应三种状态

public Luban setCompressListener(OnCompressListener listener) {compressListener = listener;return this;
}
public interface OnCompressListener {/*** Fired when the compression is started, override to handle in your own code* 压缩开始*/void onStart();/*** Fired when a compression returns successfully, override to handle in your own code* 压缩成功*/void onSuccess(File file);/*** Fired when a compression fails to complete, override to handle in your own code* 压缩失败*/void onError(Throwable e);
}

lanuch()

开始压缩,方法中使用的RxJava,根据设置的压缩等级来压缩图片


asObservable()

使用这个方法的话,采用的Rxjava方式返回一个观察者Observable。

    public Observable<File> asObservable() {if (gear == FIRST_GEAR)//判断压缩等级 return Observable.just(mFile).map(new Func1<File, File>() {@Overridepublic File call(File file) {return firstCompress(file); //调用第一档压缩方法}});else if (gear == THIRD_GEAR)return Observable.just(mFile).map(new Func1<File, File>() {@Overridepublic File call(File file) {return thirdCompress(file);// 调用第三档压缩方法}});else return Observable.empty();}

Luban存在的不足

1.不能很好的支持多图片压缩。(出现问题:多图压缩出现OOM)

2.项目使用中必须添加RxJava依赖。(已在测试项目中剔除掉RxJava依赖 「链接」



最后感谢作者 郑梓斌

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/36903.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Luban(鲁班)--图片压缩使用以及源码解析

###1.Android图片显示遇到的问题 在Android应用中加载图片&#xff0c;是一个需要消耗内存的一个动作。也是Android开发者在项目优化中比较头疼的一个问题。 先了解下加载图片如何消耗内存的 图片质量1px所占空间&#xff08;1byte8位&#xff09;1024*1024图片大小ALPHA_8只…

uni-App聊天功能的源码

前言 泡泡IM uniapp版聊天源码是一套完整的基于uniapp开发的聊天软件源码&#xff0c;可编译成微信小程序、安卓 IOS APP聊天软件、H5网页聊天室。uniapp聊天源码未加密&#xff0c;无外部依赖&#xff0c;可私有化部署&#xff0c;可二次开发。文档全面&#xff0c;接口丰富&…

一款极简聊天应用,比较完整,略好看

HasChat 基于vue3socket.io的聊天应用 无偿开源&#xff01;你们的Star是我的动力&#xff01;介绍 自我做的客服聊天以来&#xff0c;让我做一套聊天应用的呼声越来越多&#xff0c;加上那套客服聊天由于没有组件化、UI设计等问题&#xff0c;也让我一直心有遗憾做的不够完美…

鹏孚隆冲刺创业板上市:计划募资约7亿元,部分收入来自海外

12月27日&#xff0c;北京易诚互动网络技术股份有限公司&#xff08;下称“易诚互动”&#xff09;在深圳证券交易所更新招股书&#xff0c;准备在创业板上市。本次冲刺上市&#xff0c;易诚互动计划募资3.13亿元&#xff0c;将用于用于数字银行应用平台升级项目、大数据智能风…

融资破局 |中英美三国多层次资本市场和STO融资的比较及借鉴

一、引言 全球金融定价权、全球金融游戏规则&#xff0c;谁来定&#xff1f;谁是跟随者呢&#xff1f; 美国资本市场经历了200多年的发展&#xff0c;形成了当今世界上最完善、最发达的多层次资本市场体系。美国证券市场主要包括主板市场、创业板市场、场外交易市场和区域性产…

GBA Capital旗下运营公司中融环球完成1亿估值天使轮融资,由广东和合领投

近日&#xff0c;Web3.0资本平台GBA Capital宣布完成旗下运营公司中融环球估值1亿人民币的天使轮融资。中融环球主要方向为Web3.0、AI领域项目孵化及产业服务&#xff0c;致力于以教育培训、项目孵化等方式实现商业与新技术创新融合&#xff0c;实现头部品牌、企业Web3.0转型&a…

大牛书单 | 消息队列方向的好书

消息队列也通常称为消息中间件&#xff0c;提到消息队列&#xff0c;大部分互联网人或多或少都听过该名词。对于后端工程师而言&#xff0c;更是日常开发中必备的一项技能。消息队列主要解决应用耦合、异步消息、流量削锋等问题&#xff0c;具有高性能、高可用、可伸缩和最终一…

C#学习推荐书单

仅供学习参考&#xff0c;请于24小时内删除。如有版权问题请联系我。 我是从只懂C语言只看这本书入门C#, 可以参考: 《叩响C#之门》 有需要可以留言哦. 链接直达: 123云盘 如果有需要&#xff0c;可以指定某本书&#xff08;只限一本&#xff09;&#xff0c;留下邮箱&…

年度推荐书单:为你精选23本商业书

在知乎上有一个问题&#xff1a;“你在哪一刻&#xff0c;感受到了知识改变命运&#xff1f;” 巴菲特曾说&#xff0c;如果自己19岁那年没有看《聪明的投资者》这本书&#xff0c;那么整个人生轨迹会截然不同。 马云也说&#xff1a;“我第一次高考失败后做临工&#xff0c;在…

算法竞赛推荐书单

前言 入坑算法竞赛已经一年半了&#xff0c;在这期间也读了不少关于算法竞赛的书&#xff0c;这些书对我的帮助还是蛮大的。平时看题解多是个人零散的题解&#xff0c;很难以系统的去学习&#xff0c;认认真真的挑选1-2本书来阅读&#xff0c;无论是从思维能力还是文字表达能力…

IC技术圈推荐书单

《IC芯片设计中的静态时序分析实践》 作者&#xff1a;J. Bhasker, Rakesh Chadha 本书深度介绍了芯片设计中用静态时序分析进行时序验证的基本知识和应用方法&#xff0c;涉及了包括互连线模型、时序计算和串扰等在内的影响纳米级电路设计的时序的重要问题&#xff0c;并详细解…

程序员必读书单(非常经典,强烈推荐)

原文链接&#xff1a;http://lucida.me/blog/developer-reading-list/ 关于 本文把程序员所需掌握的关键知识总结为三大类19个关键概念&#xff0c;然后给出了掌握每个关键概念所需的入门书籍&#xff0c;必读书籍&#xff0c;以及延伸阅读。旨在成为最好最全面的程序员必读书单…

书单推荐

年前在图书馆借了几本书&#xff0c;这个春节带回老家看&#xff0c;没想到今年这个春节课余时间这么多&#xff0c;大致看了下&#xff0c;有三本书感觉还可以&#xff0c;推荐给大家。 1、洞见 任何决策都有边界&#xff0c;受局限。例如&#xff0c;领导者的时间精力&#x…

忆享聚焦|人工智能、AI、百川智能、机器人……近期热点资讯一览

“忆享聚焦”栏目第十五期来啦&#xff01;本栏目汇集近期互联网最新资讯&#xff0c;聚焦前沿科技&#xff0c;关注行业发展动态&#xff0c;筛选高质量讯息&#xff0c;拓宽用户视野&#xff0c;让您以最低的时间成本获取最有价值的行业资讯。目录 行业资讯 1.政企合力共推A…

震惊!人工智能引发灰色经济,ChatGPT变身罪魁祸首!

人工智能技术的日益发展和普及&#xff0c;其呈现出无边界的开发空间&#xff0c;引领出无数的商业应用&#xff0c;越来越多的领域开始依赖这一技术&#xff0c;各种应用场景日益丰富&#xff0c;而其内在的巨大潜力也被不断开发。随之而来的则是&#xff0c;因为技术的滥用和…

抖音开放平台,究竟开放了什么?

“抖音有 6 亿用户&#xff0c;我们希望连同更多的开发者在抖音里能够为用户交付更多、更优质的服务。” ——常坤 抖音开放平台负责人 作为日活超 6 亿的短视频平台&#xff0c;抖音已经渗透到我们生活的多个方面。从个人到企业甚至行业&#xff0c;从内容经营到电商消费&…

抖音怎么实现落地页跳转微信加好友?

玩抖音的朋友应该能经常看到很多商家在官网链接中或者私信界面中设置一个主页跳转页&#xff0c;然后把个人微信号或手机号嵌入其中&#xff0c;这样可以实现很好的商业用途和吸粉效果&#xff0c;事实也证明了确实有很好的吸粉效果。下面就分别大家讲一下这两种方式的具体实现…

抓包抖音充值页面实现微信支付宝充值抖币,可提供api

抖币充值系统重写升级: 1.支持配置扫码配置多个CK 2.支持生成 微信/支付宝 支付二维码 扫码充值 3.支持 微信/支付宝 APP 直接唤醒充值 体验如下: 需要的小伙伴可私信 留言&#xff01; 整个开发流程思路是以下几步&#xff1a; 1.抓包分析抖音的充值的整个流程&#xff0…

douyin web端滑动,点选验证码分析

仅用在学习交流&#xff0c;如有侵权&#xff0c;联系删除。 仅用在学习交流&#xff0c;如有侵权&#xff0c;联系删除。 仅用在学习交流&#xff0c;如有侵权&#xff0c;联系删除。 当前douyin web端&#xff0c;请求cookie中有两个很重要的参数&#xff0c;一个就是s_v_we…

抖音全接口API

​ from com.dtmilano.android.viewclient import ViewClient def search_douyin_for_recommend_user(douyin_id): # 采集指定抖音账号的关注推荐数据 # 连设备 serialno None if serialno: os.system(adbconnect{}.format(serialno or )) time.sleep(3) device, serialno Vi…