小程序根据尺寸等比压缩图片
小程序根据尺寸等比压缩图片
微信小程序官方文档有「wx.compressImage」接口可以压缩图片,但只能传入压缩质量,不能根据宽高进行压缩,用户在上传文件时如果选择了3000px以上的则比较占用储存的,前台调用加载速度也会影响。
根据搜索网上相关资料,选择使用「canvas」方式进行压缩,其原理及流程如下:
1、获取原始图片的宽高
2、根据传入的压缩宽高(如果为0则不限制)要求,把图片的原始宽高等比缩小,计算出最终压缩后的图片宽高
3、使用小程序文档接口「canvas-2d」,传入图片、宽高绘制到页面中(需用样式隐藏)
4、将「wx.canvasToTempFilePath」将画布保存为图片,生成本地临时路径
已将压缩流程封装为函数,JS代码如下:
compressImage: function(path, width, height, success) { let that = this; //获取原图片信息 wx.getImageInfo({ src: path, success: function (res) { let canvasRatio = 1.1; let picWidth = res.width; //图片原始长宽 let picHeight = res.height; let scale = picHeight / picWidth; //图片原始比例 let type = res.type == 'jpeg' ? 'jpg' : res.type; if (width == 0 && height > 0) { picWidth = Math.trunc(height / scale); picHeight = height; } else if (width > 0 && height == 0) { picWidth = width; picHeight = Math.trunc(width * scale); } else if (width > 0 && height > 0) { while (picWidth > width || picHeight > height) { picWidth = Math.trunc(res.width / canvasRatio) picHeight = Math.trunc(res.height / canvasRatio) canvasRatio = canvasRatio + 0.1; } } const query = wx.createSelectorQuery().in(that); query.select('#compress-canvas').fields({ node: true, size: true }).exec((res) => { try { const canvas = res[0].node; const ctx = canvas.getContext('2d'); let dpr = wx.getSystemInfoSync().pixelRatio; //这里是设置css样式的宽高。 //属性宽高是css样式宽高的dpr倍,兼容不同机型,避免绘制的内容模糊。 that.setData({ canvasWidth: picWidth / dpr, canvasHeight: picHeight / dpr }) canvas.width = picWidth; canvas.height = picHeight; const img = canvas.createImage() img.src = path; img.onload = () => { ctx.drawImage(img, 0, 0, picWidth, picHeight); //先画出图片 //延迟600ms,避免部分机型未绘制出图片内容就执行保存操作,导致最终的图片是块白色画板。 setTimeout(() => { wx.canvasToTempFilePath({ quality: 0.8, fileType: type, canvas: canvas, destWidth: picWidth, destHeight: picHeight, success: function (res) { // wx.compressImage({ // src: res.tempFilePath, // quality: 80, // success: function (res) { success(res.tempFilePath); // } // }) } }, that) }, 600) } } catch (e) { //异常后的操作 console.log(e); } }) } }) }
调用方法:
filePath ---- 图片路径
width ---- 需压缩的宽度
height ---- 需压缩的高度
success ---- 压缩成功函数,返回压缩后的图片路径
this.compressImage(filePath, width, height, function(path) { console.log(path); })
WXML代码:
<view class="compress-con"> <canvas type="2d" id="compress-canvas" class="compress-canvas" style="width: {{canvasWidth}}px; height: {{canvasHeight}}px;"></canvas> </view>
WXSS样式代码:
/* 压缩图片的画布 */ .compress-con{ position: relative; width: 0; height: 0; overflow: hidden; } .compress-canvas{ position: absolute; z-index: -1; top: 10000rpx; left: 10000rpx; visibility: hidden; }
PS:
「wx.canvasToTempFilePath」支持传入导入的图片质量,默认写了0.8,即80。
在微信开发者工具中,画布导出的图片大小会存在异常,可能压缩后比原图还大,在真机实测中则不会出现。
语雀:https://www.yuque.com/docs/share/9a778b7f-f190-4b82-bf28-2f4ddedb65be
密码:pplg
用户登录
还没有账号?
立即注册