封装了一个插件
使用方式:
html和css部分
//html页面底部放一个canvas元素 // 隐藏掉canvas .myCanvas{ border: solid 1rpx #ccc; position: fixed; left: -10000rpx; }
// 下面是js逻辑
let {ImageCompressor} = require("../../../utils/imageCompressor.js") // 引入插件 onLoad: function (options) { // 页面加载后初始化插件,传入必须的参数 this.imageCompressor = new ImageCompressor({ VueComponent:this, canvasId:'myCanvas', }) } ... uploadImg: function () { let that = this wx.chooseImage({ count: 9, // 默认9 sizeType: ["original", "compressed"], // 可以指定是原图还是压缩图,默认二者都有 sourceType: ["album", "camera"], // 可以指定来源是相册还是相机,默认二者都有 success: function (res) { 如果是多张图片,就调用插件的forEachCompressImg方法把res传进去,回调函数中可以获取到压缩后的图片地址 that.imageCompressor.forEachCompressImg(res,function(tempFilePath){ // 拿到压缩后的图片地址后再进行自己的上传逻辑 that.upload_file( __config.basePath + "api/upload.jsp?uid=" + that.data.uid, tempFilePath ) }) }, }) },
插件代码,建议放入到util目录下
/** * 使用Canvas进行图片缩放和压缩 * @param {Object} VueComponent vue组件的实例 * @param {String} canvasId canvas-id * @param {Number} imgMaxSize 最大的图片宽高尺寸 */ export class ImageCompressor { constructor(option) { this.VueComponent = option.VueComponent || {} this.canvasId = option.canvasId || "" this.imgMaxSize = option.imgMaxSize || 500 this.init() } init() { console.log("init done", this) } /** * 批量压缩图片函数 * @param {Object} res wx.chooseImage返回的res数据对象,通过回调返回压缩后的图片地址 * @param {Function} callBack */ async forEachCompressImg(res = {}, callBack = {}) { let that = this for (let [index, item] of res.tempFilePaths.entries()) { console.log("-----------------------------------") console.log("原始图片size:", res.tempFiles[index].size / 1024 + "k") let imgPath = res.tempFilePaths[index] let resImg = await that.imgCompress(imgPath) wx.getFileInfo({ filePath: resImg.tempFilePath, success(res) { console.log("compressImage压缩后的图片size", res.size / 1024 + "k") }, }) callBack && callBack(resImg.tempFilePath) } } /** * 单个图片压缩 * @param {String} imgSrc 临时图片路径 */ imgCompress(imgSrc = "") { let that = this let VueComponent = this.VueComponent return new Promise((resolve, reject) => { wx.getImageInfo({ src: imgSrc, success: function (res) { //---------利用canvas压缩图片-------------- var ratio = 2 var canvasWidth = res.width //图片原始长宽 var canvasHeight = res.height var limit = that.imgMaxSize // 宽高限制 while (canvasWidth > limit || canvasHeight > limit) { // 保证宽高在200以内 canvasWidth = Math.trunc(res.width / ratio) canvasHeight = Math.trunc(res.height / ratio) ratio++ } VueComponent.setData({ cWidth: canvasWidth, cHeight: canvasHeight, }) var ctx = wx.createCanvasContext(that.canvasId, VueComponent) ctx.drawImage(res.path, 0, 0, canvasWidth, canvasHeight) ctx.draw( false, setTimeout(function () { console.log(2, "压缩前图片地址", res.path) wx.canvasToTempFilePath({ canvasId: that.canvasId, destWidth: canvasWidth, destHeight: canvasHeight, quality: 0.5, // 压缩倍率 fileType: "jpg", success: function (res) { resolve(res) }, fail: function (res) { reject(res.errMsg) }, }) }, 300) //延迟500ms,避免部分机型未绘制出图片内容就执行保存操作,导致最终的图片是块白色画板。 ) }, fail: function (res) { reject(res.errMsg) }, }) }) } }