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

Android图片压缩原理(二)—— 鲁班压缩算法解析 前面几篇文章,我们了解了一些关于。 阅读详情
AI摘要

本文详细介绍了Luban图片压缩库的工作原理及其在Android应用中的使用方法。通过对比压缩前后图片的质量和大小,展示了Luban的有效性和灵活性。同时,文章也深入剖析了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>() {
                @Override
                public File call(File file) {
                    return firstCompress(file); //调用第一档压缩方法
                }
            });
        else if (gear == THIRD_GEAR)
            return Observable.just(mFile).map(new Func1<File, File>() {
                @Override
                public File call(File file) {
                    return thirdCompress(file);// 调用第三档压缩方法
                }
            });
        else return Observable.empty();
    }

Luban存在的不足

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

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



最后感谢作者 郑梓斌

Android进阶之路 - Luban 压缩图片 我记得在2017年写项目的时候图片压缩工具就是用的Luban,时隔多年后在近期的俩个项目中依旧发现了Luban的身影,所以觉得有必要好好记录一下老朋友想学习一款新技术最好的方式就是去看,因为除了会介绍基本的使用之外,如果你有兴趣的话也可以学一下源码;而我记录Blog更多的是我的一个学习、反思的过程,希望也可以帮到你。 阅读详情

相关推荐

鲁班Luban压缩图片(仿微信朋友圈压缩图片)

鲁班压缩图片Android Studio开发版,需要java1.8

可能是最详细的Android图片压缩原理分析(二)—— 鲁班压缩算法解析

第一步进行采样率压缩; 第二步进行宽高的等比例压缩(微信对原图和缩略图限制了最大长宽或者最小长宽); 第三步就是对图片的质量进行压缩(一般75或者70); 第四部就是采用webP的格式。 经过这四部的处理,基本上和微信朋友圈的效果一致,包括文件大小和显示效果 ...

weixin_44005563的博客 6486

Android图片压缩工具Luban(鲁班).zip

Luban(鲁班)——Android图片压缩工具,仿微信朋友圈压缩策略。项目描述目前做app开发总绕不开图片这个元素。但是随着手机拍照分辨率的提升,图片的压缩成为一个很重要的问题。单纯对图片进行裁切,压缩已经有很多文章介绍。但是裁切成多少,压缩成多少却很难控制好,裁切过头图片太小,质量压缩过头则显示效果太差。于是自然想到app巨头“微信”会是怎么处理,Luban(鲁班)就是通过在微信朋友圈发送近100张不同分辨率图片,对比原图与微信压缩后的图片逆向推算出来的压缩算法。因为有其他语言也想要实现 Luban,所以描述了一遍算法步骤 因为是逆向推算,效果还没法跟微信一模一样,但是已经很接近微信朋友圈压缩后的效果,具体看以下对比!效果与对比内容原图LubanWechat截屏 720P720*1280,390k720*1280,87k720*1280,56k截屏 1080P1080*1920,2.21M1080*1920,104k1080*1920,112k拍照 13M(4:3)3096*4128,3.12M1548*2064,141k1548*2064,147k拍照 9.6M(16:9)4128*2322,4.64M1032*581,97k1032*581,74k滚动截屏1080*6433,1.56M1080*6433,351k1080*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() {             @Override             public void call(Throwable throwable) {                 throwable.printStackTrace();             }         })         .onErrorResumeNext(new Func1>() {             @Override             public Observable<? extends File> call(Throwable throwable) {                 return Observable.empty();             }         })         .subscribe(new Action1() {             @Override             public void call(File file) {                 //TODO 压缩成功后调用,返回压缩后的图片文件             }         }); 标签:Luban(鲁班)

Android开发中的图片压缩——luban压缩使用介绍和源码初步梳理(1)

问题背景 安卓日常开发和学习过程中,涉及图片压缩的场景很多,比如图片上传过程等。很多时候加载的图片过多不进行图片压缩的话也是很容易出现OOM内存溢出的,本文将对安卓开发的图片压缩操作以及鲁班压缩框架进行初步的介绍,以及对鲁班压缩的源码进行初步的梳理。 问题分析 首先,介绍下安卓开发中常见的几种压缩方式: 1.质量压缩 质量...

baorant24的博客 1792

论文阅读:Visual Relationship Detection with Language Priors

Visual Relationship Detection with Language Priors(ECCV2016) 文章   尽管大多数的relationship并不常见,但是它们的object和predicate却更频繁地独立出现。paper用这个insight分别独立训练训练object和predicate的模型,然后再进行组合来预测relationship。Visual relatio...

Kivee的博客 2877

分布式定时任务(XXL-JOB)整合达梦数据库 带源码

背景 1. 因公司需要可视化管理配置调度任务,查询项目选择XXL-JOB,它是开源项目,入手很简单,详情可以参考官方文档; 2. 因项目的机密性,选择数据库为国内知名的达梦数据库7,与Java项目的整合详情可以参考SpringBoot 集成 达梦数据库 maven依赖本地jar包; 3. 因XXL-JOB暂时没有找到集成达梦数据库的案例,博主自己整合DM7踩过很多的坑,特此整合一个简单可直接...

艾斯-李的博客 3815

Luban的使用和源码解析

###Luban的使用和源码解析: 目前做App开发总绕不开图片这个元素。但是随着手机拍照分辨率的提升,图片的压缩成为一个很重要的问题。单纯对图片进行裁切,压缩已经有很多文章介绍。但是裁切成多少,压缩成多少却很难控制好,裁切过头图片太小,质量压缩过头则显示效果太差. Luban(鲁班)就是通过在微信朋友圈发送近100张不同分辨率图片,对比原图与微信压缩后的图片逆向推算出来的压缩算法. 异步调用: ...

MyselfGang的博客 3037

Windows10 Qt下用MINGW 编译VTK-8.1.0

1. 材料准备(1) 下载VTK-8.1.0: https://www.vtk.org/download/(2) 下载TIFF库: http://gnuwin32.sourceforge.net/packages/tiff.htm(直接安装即可,注意选择路径不包含中文字符)2. 安装: (1) cmake配置: a. Module下配置:勾选下图所示的六项 b. Build 配置:勾选这里能够在b...

hit1524468的专栏 3892

Luban—— Android图片压缩工具

Luban Android图片压缩工具

QG 2207

给宇树Go2机器人装‘眼睛’:在Jetson Orin Nano上从零部署YOLOv5的保姆级避坑实录

本文详细介绍了在Jetson Orin Nano上为宇树Go2机器人部署YOLOv5视觉系统的完整流程,涵盖硬件选型、环境配置、模型优化及系统集成等关键步骤。针对机器人应用场景特有的离线部署、版本冲突和实时推理等挑战,提供了实用的解决方案和性能优化技巧,帮助开发者快速实现机器人的视觉能力升级。

weixin_29169505的博客 378

uniapp 基于单选框多选框实现上拉触底多选/单选、回显

showPickerCheckbox弹层显示 label和value 类似下拉框的label和value一个意思 键和值。结果:可以传接口(接口只能post请求) 可以搜索 下面是结果图片展示 单选多选都可以。fieldValue回显传的值 传的是字符串 数组的话[1,2]转为1,2格式传入。mode是控制的单选还是多选 true为多选默认值 其余参数 单选多选一样。fieldName字段名 确定后会返回该字段名 根据字段名找对应的传入值。问题:在uniapp上 实现分页多选的操作。下面是组件的完整代码。

2301_76607997的博客 2936

最接近微信的图片压缩方案:10分钟上手Luban算法

你是否还在为App中的图片加载缓慢而烦恼?用户抱怨相册上传卡顿、流量消耗过大?Luban(鲁班)图片压缩工具或许能解决这些问题。作为一款接近微信朋友圈压缩效果的Android图片处理库,Luban通过智能算法将13M的拍照原图压缩至140k左右,同时保持视觉质量几乎无损。本文将带你从参数调优到可视化调试,全面掌握这一高效压缩方案。 ## 为什么选择Luban? Luban的核心优势在于其算法设...

gitblog_00907的博客 1211

Agent框架系列:1-低代码智能体平台深度解析Dify、Coze、n8n

Dify、Coze 和 n8n 是三大主流低代码智能体平台,各有侧重。Dify 适合企业级 AI 应用,具备强大的 RAG 和知识库管理能力,技术栈为 Python + React。Coze 由字节推出,主打零代码和快速原型开发,集成 60+ 插件,极适合非技术用户。n8n 以工作流自动化和系统集成为核心,支持 400+ 外部应用,基于 Node.js + Vue,扩展性极强。选择建议:非技术团队选 Coze,AI 应用选 Dify,复杂自动化与集成选 n8n。可根据实际需求混合使用,最大化平台优势。

3087

告别繁琐配置:Luban Gradle插件实现图片压缩参数自动化

你是否还在为Android项目中的图片压缩参数配置而烦恼?手动调整压缩阈值、格式和尺寸比例不仅耗时,还难以保证效果一致性。本文将介绍如何通过Luban(鲁班)的Gradle插件实现图片压缩参数的自动化管理,让你彻底摆脱重复劳动,专注于业务开发。读完本文后,你将掌握: - Luban压缩算法的核心优势 - Gradle插件的自动化配置技巧 - 多场景下的参数优化方案 - 完整的集成与调试流程 #...

gitblog_00857的博客 489

运行后选择GDB/LLDB出现这样的窗口:launch: program ‘输入程序名称,例如 D:\Desktop\新建文件夹\a.exe‘ does not exist...如何解决?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 1129

RK3568适配MIPI屏幕触摸,触摸延时很大

我用的是系统,接了一个,设备树已经正确配置,evtest测试坐标值和触摸位置都是准确的。但是出现了一个:我在屏幕上点一下,要等大约 2 秒才能在evtest里看到坐标事件打印。这种现象在 Goodix 系列触摸驱动里比较少见,一般意味着。

小灰灰的博客 1363

Luban

Luban前言一、Luban是什么?二、使用步骤1.引入库2.使用3.API三、算法作者地址 前言 自己写的bitmap压缩不够优秀,找了个优秀的图片压缩框架 一、Luban是什么? Luban(鲁班) —— Android图片压缩工具,仿微信朋友圈压缩策略。 二、使用步骤 1.引入库 implementation 'top.zibin:Luban:1.1.8' 2.使用 一张一张压缩 Observable.fromIterable(images ==

嗯... 2512

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

OpenCore Legacy Patcher 完整教程:让老款 Mac 免费用上最新 macOS

Apple 早已停止给老机型推送系统更新,可它们的硬件明明还能再战。OpenCore Legacy Patcher(OCLP)就是在引导阶段注入兼容补丁,让旧款 Intel Mac 装上新版 macOS 的免费工具。全程涉及格式化操作,**先把重要数据备份好**。 ## 原理速览:OCLP 如何绕过系统限制 OCLP 并不改动磁盘里的系统本体。开机时,OpenCore 引导加载器会提前把补丁载

gitblog_00232的博客 731

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

实测超越微信?Luban 1.1.8让图片压缩效率再突破

如果觉得这个压缩工具对你有帮助,记得点赞收藏关注三连!下期我们将带来Luban与其他压缩库的性能横评,敬请期待。

gitblog_00055的博客 1067

终极指南:Luban压缩算法如何实现微信朋友圈级别的图片优化

Luban(鲁班)是一款高效的图片压缩工具,其压缩效果非常接近微信朋友圈的图片压缩算法。本文将深入解析Luban的核心压缩技术,带您了解如何通过比例区间决策树实现高质量图片压缩,帮助开发者轻松集成到自己的项目中。 ## 📊 为什么选择Luban压缩算法? 在移动应用开发中,图片压缩是提升用户体验的关键环节。过大的图片会导致加载缓慢、流量消耗增加,而过低的压缩质量又会影响视觉效果。Luban压

gitblog_00996的博客 389

Luban 2(鲁班 2)Android 图片压缩库完全指南:微信朋友圈压缩策略的像素级还原与 Kotlin/TurboJPEG 深度优化

Luban 2(鲁班 2)是一款面向 Android 的高效图片压缩工具库,其核心思路是通过逆向推算微信朋友圈的压缩策略,在图片体积与显示画质之间找到最优平衡点。本文以 [README.md](https://link.gitcode.com/i/3f19b08b8d5dac5373b7c5c47b6d5e0f) 为主线,结合仓库中的算法实现、协程 API、TurboJPEG 原生层、单元测试与示

gitblog_00365的博客 253

实测!Luban同步异步压缩速度深度对比:谁才是移动端图片处理之王?

你还在为图片压缩太慢导致APP卡顿烦恼吗?还在纠结同步压缩阻塞UI线程还是异步压缩延迟高的问题吗?本文将通过实测对比Luban(鲁班)图片压缩算法的同步与异步模式性能差异,让你3分钟搞懂两种模式的适用场景,轻松解决移动端图片处理难题。 读完本文你将获得: - 同步/异步压缩的核心差异解析 - 3组真实设备性能测试数据对比 - 基于场景的最佳压缩模式选择指南 - 完整的代码集成示例与优化建议 #...

gitblog_00367的博客 478

彻底解决Luban图片压缩残留:Android应用卸载后缓存清理全方案

你是否遇到过这样的困扰:明明卸载了使用Luban(鲁班)图片压缩算法的Android应用,手机存储空间却没有明显释放?这很可能是因为Luban生成的压缩图片缓存文件没有被彻底清理。本文将从技术原理到实战操作,全面解决这一问题,让你的应用在用户卸载后不留痕迹。 读完本文你将获得: - 了解Luban缓存文件的存储机制 - 掌握3种彻底清理缓存的实现方案 - 学会在应用开发中预防缓存残留问题 - 获...

gitblog_00512的博客 489

告别无效压缩!Luban ignoreBy参数的黄金阈值设置指南

你是否遇到过这样的困境:使用Luban压缩图片时,小图被过度压缩导致模糊,大图却因未触发压缩而体积超标?作为最接近微信朋友圈压缩算法的图片处理库,Luban的ignoreBy参数正是解决这一矛盾的关键。本文将通过源码解析和场景测试,帮你找到不同业务场景下的最优阈值,让每张图片都获得恰到好处的压缩处理。 ## 参数原理:为什么100KB成为默认阈值? Luban的压缩触发机制由双重条件控制:文件...

gitblog_00276的博客 1006

Luban错误处理全解析:常见异常与解决方案

你是否遇到过图片压缩时的神秘崩溃?是否因压缩失败导致用户投诉?Luban(鲁班)作为接近微信朋友圈压缩效果的Android图片压缩库,在实际开发中仍会遇到各类异常。本文将系统梳理Luban的7类核心异常,提供12种解决方案及6个最佳实践,帮你构建健壮的图片压缩模块。 读完本文你将掌握: - 快速定位Luban压缩失败的根本原因 - 实现零崩溃的异常处理机制 - 优化压缩成功率的实战技巧 - 构建...

gitblog_00273的博客 529

Apache License 2.0完整指南:Luban开源协议使用规范详解

Apache License 2.0是目前最受欢迎的开源协议之一,Luban项目正是采用这一协议来保护开发者的权益。作为可能是最接近微信朋友圈的图片压缩算法,Luban在Apache 2.0协议下为用户提供了自由使用、修改和分发的权利。😊 ## 📋 Apache 2.0协议核心要点 Apache License 2.0协议为使用者提供了极大的自由度,同时确保了原作者的权益得到保护。 ##

gitblog_00740的博客 552
上一篇: RxJava 系列学习
下一篇: vlayout使用解析
疯狂小凯哥
博客等级 码龄10年 79粉丝 17原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值