当前位置: 首页 > news >正文

社区网站建设与开发论文怎么写/优化落实疫情防控

社区网站建设与开发论文怎么写,优化落实疫情防控,制作外贸型网站,企业网站建设合同百度文库我记得在2017年写项目的时候图片压缩工具就是用的Luban,时隔多年后在近期的俩个项目中依旧发现了Luban的身影,所以觉得有必要好好记录一下老朋友 想学习一款新技术最好的方式就是去看 官方文档(Github - Luban) ,因为除…

我记得在2017年写项目的时候图片压缩工具就是用的Luban,时隔多年后在近期的俩个项目中依旧发现了Luban的身影,所以觉得有必要好好记录一下老朋友

想学习一款新技术最好的方式就是去看 官方文档(Github - Luban) ,因为除了会介绍基本的使用之外,如果你有兴趣的话也可以学一下源码;而我记录Blog更多的是我的一个学习、反思的过程,希望也可以帮到你

      • 基本了解
        • 压缩效果
        • 压缩算法
        • 方法列表
      • 基础使用
        • 异步调用
        • 同步调用
      • 项目实战

基本了解

Android市场 相比 Ios市场 更具有开放性、广泛性;在国内也有着众多厂商,同时意味着也有更多的手机品牌,这就面临着每款手机的 拍照分辨率,屏幕显示分辨率 可能有所不同,故而就会出现一些小问题;

随着手机拍照分辨率的提升,图片压缩就是一个很重要的问题;如果只是单纯对图片进行裁切,压缩可能很难满足诉求(关于原始压缩方式和原理,等后续有时间补一篇),这是因为没有一个标准,如果裁切过头图片太小,质量压缩过头则显示效果太差

个人见解:所谓的标准,可以说是策略,指的是不同场景下采用不同的方式(如果不理解,可以看看 策略模式,开放下思维)

在一些项目实战场景,可以看出图片压缩的重要性,例如~

  • 加载大图时浪费太多流量,同时还可能发生OOM(现在)
  • 上传大图时浪费太多流量,同时还可能出现上传失败的结果

压缩效果

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

同一张图片经过 Luban压缩 WeChat压缩 de 效果与对比(压缩效果很好,所以沿用到了现在)

在这里插入图片描述

压缩算法

作者考虑到其他语言也想要实现Luban,所以描述了一遍算法步骤

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

作者在2018、2019年后就没再维护了,有俩种可能一种就是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 传入压缩流程,压缩图片直到满足以上数值

方法列表

方法描述
load传入原图
filter设置开启压缩条件
ignoreBy不压缩的阈值,单位为K
setFocusAlpha设置是否保留透明通道
setTargetDir缓存压缩图片路径
setCompressListener压缩回调接口
setRenameListener压缩前重命名接口

基础使用

以下使用方式在 Luban 都可以看到,是作者提供的一些调用示例,方便大家快速使用

build.gradle 引入依赖

 implementation 'top.zibin:Luban:1.1.8'

异步调用

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

 Luban.with(this).load(photos).ignoreBy(100).setTargetDir(getPath()).filter(new CompressionPredicate() {@Overridepublic boolean apply(String path) {return !(TextUtils.isEmpty(path) || path.toLowerCase().endsWith(".gif"));}}).setCompressListener(new OnCompressListener() {@Overridepublic void onStart() {// TODO 压缩开始前调用,可以在方法内启动 loading UI}@Overridepublic void onSuccess(File file) {// TODO 压缩成功后调用,返回压缩后的图片文件}@Overridepublic 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();

项目实战

以下均为我在项目中使用Luban的一些伪代码,可供借鉴

ImageCompressor

package com.jsmedia.jsmanager.utils.imgUtilsimport android.content.Context
import top.zibin.luban.Luban
import top.zibin.luban.OnCompressListener
import java.io.Fileobject ImageCompressor {private const val IGNORE_SIZE = 1fun compress(context: Context, imageFile: File, compressResult: CompressResult) {Luban.with(context).load(imageFile).ignoreBy(IGNORE_SIZE).setCompressListener(object : OnCompressListener {override fun onStart() {}override fun onSuccess(file: File) {compressResult.onSuccess(file)}override fun onError(e: Throwable) {compressResult.onError(e)}}).launch()}interface CompressResult {fun onSuccess(file: File)fun onError(e: Throwable)}
}

调用方式

	ImageCompressor.compress(this@StorePhotoActivity,File(filePathByUri),object : ImageCompressor.CompressResult {override fun onSuccess(file: File) {}override fun onError(e: Throwable) {}})

项目 - 伪代码

    /*** 拍照* */fun onCamera(view: View?) {ImagePicker.getInstance().startCamera(this, false, object : PickCallback() {override fun onPermissionDenied(permissions: Array<String?>?, message: String?) {ToastUtils.showShort(message)}override fun cropConfig(builder: ActivityBuilder) {builder.setMultiTouchEnabled(true).setGuidelines(CropImageView.Guidelines.ON_TOUCH).setCropShape(CropImageView.CropShape.OVAL).setRequestedSize(400, 400).setFixAspectRatio(true).setAspectRatio(1, 1)}override fun onPickImage(imageUri: Uri?) {super.onPickImage(imageUri)Log.e("tag", imageUri.toString())var bitmap = BitmapFactory.decodeStream(imageUri?.let {contentResolver.openInputStream(it)});var filePathByUri = FileUtil.getFilePathByUri(this@StorePhotoActivity, imageUri)ImageCompressor.compress(this@StorePhotoActivity,File(filePathByUri),object : ImageCompressor.CompressResult {override fun onSuccess(file: File) {mViewModel.upload(2,"album",file.absolutePath,MMKV.defaultMMKV().decodeString("storeId").toString())}override fun onError(e: Throwable) {}})}override fun onCropImage(imageUri: Uri?) {}})}/*** 相册* */fun onGallery(view: View?) {ImagePicker.getInstance().startGallery(this, false, object : PickCallback() {override fun onPermissionDenied(permissions: Array<String?>?, message: String?) {ToastUtils.showShort(message)}override fun onPickImage(imageUri: Uri?) {Log.e("tag", imageUri.toString())var bitmap = BitmapFactory.decodeStream(imageUri?.let {contentResolver.openInputStream(it)});var filePathByUri = FileUtil.getFilePathByUri(this@StorePhotoActivity, imageUri)ImageCompressor.compress(this@StorePhotoActivity,File(filePathByUri),object : ImageCompressor.CompressResult {override fun onSuccess(file: File) {mViewModel.upload(2,"album",file.absolutePath,MMKV.defaultMMKV().decodeString("storeId").toString())}override fun onError(e: Throwable) {}})}})}override fun onRequestPermissionsResult(requestCode: Int,permissions: Array<String?>,grantResults: IntArray) {super.onRequestPermissionsResult(requestCode, permissions, grantResults)ImagePicker.getInstance().onRequestPermissionsResult(this, requestCode, permissions, grantResults)}override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)ImagePicker.getInstance().onActivityResult(this, requestCode, resultCode, data)}
http://www.jmfq.cn/news/5181805.html

相关文章:

  • 花店网站推广方案/企业网站优化关键词
  • 重庆专业的网站建设公司排名/深圳创新创业大赛
  • mvc做的网站/广东网站seo策划
  • 网站建设ssc源码/域名whois查询
  • 建筑类招聘网站有哪些/成都seo优化排名公司
  • 湛江网站建设托管/网站友情链接购买
  • 广西麒铭建设有限公司网站/百度排名优化
  • 视频网站如何做营销策划/关键词整站优化
  • 高端网站建设推来客网络/西安抖音seo
  • 南头专业外贸网站建设公司/seo咨询茂名
  • qq网页登录/宁波seo入门教程
  • 烟台网站制作套餐/美国搜索引擎排名
  • 公司怎么建立自己网站/seo站长工具查询系统
  • 福州仓山区网站建设/软广告经典案例
  • 北京市海淀区建设委员会网站/自动搜索关键词软件
  • wordpress进入数据库/百度seo优化价格
  • 物流公司怎么做网站/手机百度网盘下载慢怎么解决
  • 北京网站模板建设/今日头条号官网
  • 鞍山网站制作公司/网络营销成功案例分析
  • 创意广告图片/哈尔滨百度搜索排名优化
  • 网站开发线上销售技巧/营销网络怎么写
  • 推荐一些做电子的网站/搜索引擎排名竞价
  • wordpress主题dux/西安seo网站推广优化
  • 给我免费播放片高清在线观看中国/百度刷排名优化软件
  • 网站主题制作/seo优化关键词是什么意思
  • 广州微信网站设计/优化推广关键词
  • php网站开发更换模板/做国外网站
  • 做网站如何挣钱/六盘水seo
  • 服务类网站开发/谷歌app官方下载
  • 教你做企业网站/深圳搜索竞价账户托管