步骤: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>
你好,麻烦提供出现问题的具体机型、微信版本号、系统版本号,以及能复现问题的代码片段(https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html)
请问楼主问题解决了吗,我也遇到同样的问题