请问楼主问题解决了吗,我也遇到同样的问题
救命啊,选择的图片用canvas缩小重绘后图片文件大小变大了?步骤:1 选择图片文件得到图片的地址数组 2 获取文件的大小 [(path,width,height}] 3创建离屏水印画布,将水印图片绘制到离屏画布上,得到离屏图片对象宽475高475 以下用的画布不是离屏画布 4.1返回SelectorQuery 对象实例 4.2依据画布的id得到canvas 4.3循环==》选择的图片次数 4.3.1清除画布区域内容 大小为选择的图片的大小 4.3.2创建图片对象 4.3.3依据选择的图片的大小缩放画布:宽高大于3200时缩小为3200,小于800时放大为800(依据原图比例缩放) 4.4.4将绘制选择的图片 4.4.5绘制水印图片 4.4.6把画布生成图片 5.上传图片至云 完毕 问题:选择的图片的宽高超过3200, 经缩放画布后绘制,生成的图片大小体积反超原图片2倍以上(在云开发==>存储里面可见) 可能有的东西我没理解对,不知道哪里错了???求解 以下源码: index.js const app = getApp() var _this Page({ data: { canvas: { width: 800, height: 800 } }, onLoad() { _this = this }, //选择图片 bindtap: function () { wx.chooseImage({ success(res) { _this.compress(res.tempFilePaths) //_this.tempFilePaths = res.tempFilePaths }, fail(err) { console.log('选择图片错误', err) } }) }, /** * 压缩图片 * @param {*} tempFilePaths //所选图片的地址 数组 */ compress: async function (tempFilePaths) { //===========================================================================生成 水印 watermarkImage 对象 ↓↓↓↓↓↓↓↓↓↓↓ const offCanvas = wx.createOffscreenCanvas({ //离屏画布 上面绘制的是小程序二维码 type: '2d', width: 475, height: 475 }) const offContext = offCanvas.getContext('2d') //离屏绘图上下文 const watermarkImage = offCanvas.createImage() //小程序二给码的水印图片 await new Promise(resolve => { watermarkImage.onload = resolve, watermarkImage.src = '/image/小程序体验版.jpg' //小程序的二维码 }) offContext.clearRect(0, 0, 475, 475) //清除画布内容 offContext.drawImage(watermarkImage, 0, 0) //将水印绘制在画布上 //===========================================================================生成 水印 watermarkImage 对象 ↑↑↑↑↑↑↑↑↑↑↑ let imageS = [] //最终绘制好的图片 //===========================================================================获取图片的 宽 高 路径 ↓↓↓↓↓↓↓↓↓↓↓ let imageArr = [] //图片数组[{路径,宽,高}] for (let i = 0, len = tempFilePaths.length; i < len; i++) { imageArr[i] = await GetImageInfo(tempFilePaths[i]) //获取图片属性 } //===========================================================================获取图片的 宽 高 路径 ↑↑↑↑↑↑↑↑↑↑↑ //=========================================================================== 压缩图片 过大时缩小画布 过小是放大画布↓↓↓↓↓↓↓↓↓↓↓ const query = wx.createSelectorQuery() //返回一个 SelectorQuery 对象实例 const canvas = await new Promise((resolve, reject) => { query.select('#myCanvas') //在当前页面下选择第一个匹配选择器 selector 的节点。返回一个 NodesRef 对象实例,可以用于获取节点信息 得到id为myCanvas的节点信息 .fields({ //获取节点的相关信息 node: true, //是否返回节点对应的 Node 实例 size: true //是否返回节点尺寸 }) .exec((res) => { if (res[0] && res[0].node) { resolve(res[0].node) } else { reject(res) } }) }) const ctx = canvas.getContext('2d') for (let i = 0, len = imageArr.length; i < len; i++) { ctx.clearRect(0, 0, imageArr[i].width, imageArr[i].height) //清除画布上该区域的内容 let image = canvas.createImage() //创建一个图片对象 await new Promise(resolve => { //等待图片加载完成 image.onload = resolve image.src = imageArr[i].path // 要加载的图片 url }) let { CW, CH } = zoomCanvas(imageArr[i].width, imageArr[i].height) //返回画布的宽高 console.log('原图宽:' + imageArr[i].width + '原图高:' + imageArr[i].height + '画布宽' + CW + '画布高' + CH) canvas.width = CW; canvas.height = CH; ctx.drawImage(image, 0, 0, CW, CH) //绘制缩放后的图片 ctx.drawImage(watermarkImage, 0, 0, 475, 475, CW - 475, CH - 475, 475, 475)//右下角绘制水印(二维码) imageS[imageS.length] = await produce(canvas, CW, CH) //生成图片 } //=========================================================================== 压缩图片 过大时缩小画布 过小是放大画布↑↑↑↑↑↑↑↑↑↑↑ /** * 问题:???????????????????????????????????????????????????? * 完成后这里上传图片文件至云(采用云开发,上传至) * 打开 云开发->存储->找到文件所在位置 * 发现图片文件大小严重超过原图的大小(在选择图片时选择的是宽高在3200以上的) * 但在绘制图片前,控制台输出的 原图宽高 和 画布宽高 正确按比例缩小了 * 求解:本人老白,不太懂哪里错了????????????????????????????? */ _this.setData({ imageS: imageS }) }, /** * 预览图片 */ image_tap:function(){ wx.previewImage({ urls:_this.data.imageS }) } }) /** * 缩放画布 返回缩放的大小 * @param {number} imageW 所选图片的宽 * @param {number} imageH 所选图片的高 */ function zoomCanvas(imageW, imageH) { let CW = imageW let CH = imageH let multiple = 1 //定义缩放的倍数 if (CW > 3200) { multiple = 3200 / imageW //定义缩放的倍数 } else if (CH > 3200) { multiple = 3200 / imageW //定义缩放的倍数 } else if (CW < 800) { multiple = 800 / imageW //定义缩放的倍数 } else if (CH) { multiple = 800 / imageW //定义缩放的倍数 } CW = parseInt(imageW * multiple) CH = parseInt(imageH * multiple) _this.setData({ //刷新页面画布宽高 canvas: { width: CW, height: CH } }) return { CW, CH } } /** * 获取图片的宽高路径 返回图片路径 宽 高 * @param {string} path 图片路径数组 */ async function GetImageInfo(path) { return new Promise((resolve, reject) => wx.getImageInfo({ src: path, success(res) { resolve({ path: res.path, width: res.width, height: res.height }) }, fail(err) { reject(err) } })) } /** * 生成图片 返回生成的图片地址 * @param {object} canvas 图片对象 * @param {number} width 要输出的图片的宽 * @param {number} height 要输出的图片的高 */ function produce(canvas, width, height) { return new Promise((resolve, reject) => wx.canvasToTempFilePath({ canvas: canvas, destWidth: width, //输出的图片的宽 destHeight: height, //输出的图片的高 fileType: 'jpg', //生成的图片格式 success(res) { resolve(res.tempFilePath) }, fail(err) { reject(err) } })) } /** * 保存文件 * @param {arr} imageS 文件地址数组 */ function preservation(imageS) { let catalogue=wx.env.USER_DATA_PATH//文件系统中的用户目录路径 (本地路径) let C=0 for(let i=0,len=imageS.length;i<len;i++){ wx.saveFileToDisk({ filePath:catalogue+'/image/水印图片/'+i+'jpg', success(res){ console.log(res) }, fail(err){ console.error('保存文件失败',err) } }) } } .html <label wx:for="{{imageS}}" wx:key='key'> <image src="{{imageS}}"bindtap='image_tap'></image> </label> <button bindtap="bindtap">选择图片</button> <canvas type='2d' id="myCanvas" style="width:{{canvas.width}}rpx; height:{{canvas.height}}rpx;"></canvas>
2022-05-12