这篇文章主要给大家介绍了关于微信小程序对图片进行canvas压缩的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
微信小程序其实自带一个图片压缩的API wx.compressImage,但是这玩意目前感受就是个垃圾。IOS大多数情况下据说还可以,安卓有的时候降低质量压缩后体积反而变大,而且没办法控制其压缩至具体指定的大小,压缩后多大看天意。所以需要使用画布去自己实现一个图片压缩方法。
简单来讲原理就是:找个不显示在页面上的画布画上去,再取出,如果体积还是太大,缩小尺寸后再画,再取,递归下去,直到体积满足要求。(所以限制的越小,图片越大,压缩越久,递归次数越多)
第一步:新建一个zipPic.js文件(名字你开心就好),里面的代码如下
//通过canvas将图片压缩至指定大小
//判断图片大小是否满足需求,limitSize的单位是kb
//将图片画在画布上并获取画好之后的图片的路径
//图片画上去,imageW和imageH是画上去的尺寸,图像和画布间隔都是0
//这里一定要加定时器,给足够的时间去画(所以每次递归最少要耗时200ms,多次递归很耗时!)
quality:1, //最高质量,只通过尺寸放缩去压缩,画的时候都按最高质量来画
//初始值传入为画布自身的边长(我们这是一个正方形的画布)
//判断图片尺寸是否满足要求
//满足要求走callback,将压缩后的文件路径返回
//不满足要求需要压缩的时候
这里的目的是当绘画区域缩小的比图片自身尺寸还要小的时候
取图片长宽的最大值,然后和当前绘画区域计算出需要放缩的比例
然后再画经过放缩后的尺寸,保证画出的一定是一个完整的图片。由于每次递归绘画区域都会缩小,
所以不用担心scale永远都是1绘画尺寸永远不变的情况,只要不满足压缩后体积的要求
就会缩小绘画区域,早晚会有绘画区域小于图片尺寸的情况发生
//图片在规定绘画区域上画并获取新的图片的path
再去检查是否满足要求,始终缩小绘画区域,让图片适配绘画区域
这里乘以0.95是必须的,如果不缩小绘画区域,会出现尺寸比绘画区域小,
而体积比要求压缩体积大的情况出现,就会无穷递归下去,因为scale的值永远是1
但0.95不是固定的,你可以根据需要自己改,0到1之间,越小则绘画区域缩小的越快
但不建议取得太小,绘画区域缩小的太快,压出来的将总是很糊的
好的接下来是使用的方法:
在你想压缩图片的js代码所对应的页面中。先放置一个用户看不见的画布。
<!--用于图片压缩的canvas画布,不在页面中展示,且id固定不可变-->
其中cw的值我个人建议选择用户屏幕的宽度,如下,在page({…})的data中添加
个人建议画布和绘画区域都是正方形的,毕竟你也不知道要压缩的图片是横向的还是纵向的。
//resPath就是压缩后图片的路径,然后想做什么都随你
- 这里代码的主体不是我做的,网上一搜基本都是这个写法,这里是经过项目实践测试后没问题了做的讲解。
- 这里图片是只选了一张去压缩,如果你需要选多张再挨个压缩那就去写个循环,找个数组存压缩后的结果,网上也有很多内容。
- 回调函数中有lessRes和moreRes,细心的会发现这两个参数并没有被用到,他们只是个提醒作用,表明当前是less回调还是more回调,如果你不怕弄混删掉了或者自己另外写了两个新方法那都随你。
- 极限情况下比如说将图片强制压缩至10kb,这个东西我没测试过,不知道会不会有问题。
- 图片压缩体积的减小不是线性的,给人的感觉有点像二次函数(y=x^2左面那一半),越往后压缩的尺寸变化会越小。当然,这和用户的分辨率,屏幕本身的大小都有关系。
- 还是那句话,由于每次递归都要给至少200ms的时间去画,所以递归很耗时!!!而不递归进行压缩的话,网络传输又会很耗时!!!所以这个地方怎么取舍,压缩至多大,绘画区域缩小的多快,都要靠你自己的经验去调试。
- 图片的压缩,长宽比理论上来讲是不变的,但是因为舍弃了小数,可能会有肉眼难以察觉的误差,但是问题不大。如果前端想展示一下压缩后的图片的话,不要忘记在image中加入mode=“aspectFit” 。
到此这篇关于微信小程序对图片进行canvas压缩的文章就介绍到这了,更多相关微信小程序对图片canvas压缩内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
}
无论是app还是小程序或者其他端,交互中请求无处不在。
一个优秀的封装类,能让你的开发效率事半功倍,所以封装逻辑至关重要,当然我也是个小菜鸟,跟着自己的思路写过一些封装方法,一方面是想不足之处还望路过的大神给予指正,二者是为新手打开一个善于封装思维的大门,下面进入到前置知识。
Ts: 简易的类型声明、接口等
Taro:类react,以及小程序基础知识等
其中利弊不多做介绍,我们将会用到promise的请求方式。
2.梳理会用到的请求结构,以及定义的文件分类:
- 接口地址,也就是我们常说的url,存放于api.ts文件中
- 请求方法,也就是我们封装的方法,我们存放于request.ts文件中
- 接口类型,也就是我们声明数据类型的文件,我们存放于inter.d.ts文件中
-
配置文件,常用的全局请求域名,其他不动参数等,我们这里只是简单的示例因此不需要,如果有需要请大家自行配置
|
存放接口地址、以及统一请求域名前缀
|
封装公共请求方法、以及调用方法集合
|
ts的声明文件,主要存放返回值类型,请求参数类型等
|
3.接入promise声明自己的方法并返回自己的promise请求对象
我这里尽量写es6写法让大家在今后的项目开发中更加顺畅的使用,当然在自己的项目中请结合实际情况使用,不要盲目的接入一些新的写法。下面进入知识点梳理:
- loading文字参数可自定义
- 请求失败是否弹出我们的报错信息
- url在不以http/https的情况下使用自定义接口
4.分离请求参数并使用ts声明传入值与类型
1.将使用到的参数进行分离 2.每个参数给出默认值,如果不传人将用默认值代替 3.使用ts声明参数类型
上面的header,我重新定义了一个接口来声明类型,是为了更方便的去管理这个数据,试想如果我们平时需要将用户的token带入到header里面,那么我们就会在RequestHeader中在声明一个token字段。
所谓的接口也就相当于我们这个数据里面有什么字段,字段是什么类型。
所以,我们在header中在加入token字段,实际项目中,可能还会带入加密串,时间,以及其他的辅助验证字段,这里只为了大家方便开发做出示例,实际还需看项目声明。
特殊提醒:ts是可以不加逗号的
声明我们的默认参数,在用户没有参数传入的情况下,将会使用我们的默认参数来辅助请求。
思考问题,我们如果每次动态 带上我们token? 用户刚开始进入小程序,这时可能是没有授权,后面授权了我们要及时更新token来达到用户交互目的 这时我们可以将header提出,当然我一般会在我的状态管理中操作,这里做个例子为大家提供思路。
- 将token作为可选字段
- 封装方法每次请求动态提取token
- 方法返回类型为我们定义的RequestHeader类型
5.在参数某些字段不传入的情况下,我们使用自己的参数字段进行默认填充
思考问题:RequestBase参数都是必传,但是我们的请求的时候参数都是可传,如果我们将其都改为可选参数,这个时候如果我们使用req.title(loading标题)、req.url('请求api地址') 在ts的检测下,这些参数都是可能不存在的,这样我们会写大量判断,那么我们的代码就会变得相当糟糕~!因此我们再声明一个接口用来可选参数的规范。
改造请求方法,并声明各个类型,使ts更加规范, 将接口类使用inter导入,也将之前的api改成Api统一首字母大写
ok,请求方法写到这里我们暂时只能告一段落了
6.完善api.ts,声明全局域名以及每个接口的定义.
8.自定义获取方法,结合自己的请求方法返回新的promise对象
9. 页面内可以调用getTopics方法拿到我们的数据
至此,一个简易的封装就完美的结束了,但是在实际开发中为了自己的便利,我们会封装很多经常使用到的参数,这里只是提供一个封装思维,具体还需要在大家的项目中去思考怎么才能去优化代码。
- ts:类型声明, 可选项, type , any类型 ,单个类型定义
免责声明:本站所有文章和图片均来自用户分享和网络收集,文章和图片版权归原作者及原出处所有,仅供学习与参考,请勿用于商业用途,如果损害了您的权利,请联系网站客服处理。
}