业务需求:选择图片添加水印,并保存,或上传
技术要点:画布,图片选择、上传、保存
首先需要一个图片容器和一个画布
<view class='Photograph' bindtap='Photograph' style='background:{{background}}'>
<image src='../../images/messageinput/Photograph.png' id='Photographimg' style="display:{{istake==0?'flex':'none'}}"></image>
<view id='Photographtext' style="display:{{istake==0?'flex':'none'}}">拍照上传</view>
<image src='{{backgroundimage}}' id='photo' style="display:{{istake==1?'flex':'none'}}" mode='aspectFit'></image>
</view>
<canvas class='canvas' style="width:{{canvasWidth}}px;height:{{canvasHeight}}px;left:{{canvasWidth*2}}px;" canvas-id="firstCanvas"></canvas>
其中画布需要设置left的原因是将画布位移到屏幕看不见的地方,不能使用display:none,会直接导致画布无法使用
逻辑:
(1)点击图片模块,选择手机中图片,先显示到图片模块中
(2)调用wx.getImageInfo
获取图片宽高,设置canvas宽高
(3)使用canvas制作水印
(4)保存或上传已有水印图片
代码解析:
wx.chooseImage({
count: 1, //只选择1张图片
sizeType: ['compressed'], //图片大小,这里选的压缩图,怕原图处理水印性能有问题
sourceType: ['album', 'camera'],
success: function(res) {
that.setData({
tempfilePaths: res.tempFilePaths[0],
istake: 1,
backgroundimage: res.tempFilePaths[0], //显示为选择的图片
background: ""
})
}
})
wx.getImageInfo({
src: res.tempFilePaths[0], //在chooseImage的success中调用,res.tempFilePaths[0]为选择的图片
success: (ress) => {
console.log(ress)
let date = util.formatTime(new Date()); //获取当前的时间,作为水印
let ctx = wx.createCanvasContext('firstCanvas') //创建画布
let textToWidth = ress.width / 3 * 0.5 //这里设置的是水印位置
let textToHeight = ress.height / 3 * 0.9
that.setData({
canvasHeight: ress.height / 3, //画布大小,除以三是变小处理快,自行修改
canvasWidth: ress.width / 3
})
//将图片src放到cancas内,宽高为图片大小
ctx.drawImage(res.tempFilePaths[0], 0, 0, ress.width / 3, ress.height / 3)
//将声明的时间放入canvas
ctx.setFontSize(14) //注意:设置文字大小必须放在填充文字之前,否则不生效
ctx.setFillStyle('blue')
ctx.fillText(date, textToWidth, textToHeight) //水印内容,位置
// ctx.strokeText(date, ress.width, ress.height)
wx.showLoading({
title: '制作水印中...',
})
ctx.draw(false, () => { //开始制作
setTimeout(()=>{ //使用定时是因为制作水印需要时间,设置定时才不会出bug
wx.canvasToTempFilePath({ //将画布中内容转成图片,即水印与图片合成
canvasId: 'firstCanvas',
success: (res) => {
console.log(res)
that.setData({
backgroundimage: res.tempFilePath,
shuiyinPaths: res.tempFilePath
})
wx.hideLoading()
wx.saveImageToPhotosAlbum({ //保存到手机
filePath: res.tempFilePath,
success(res) {
console.log('1')
}
})
}
})
},
fail: (e) => {
console.log(e)
}
})
},500)
}
)
}
})
完整代码(其中有一些我项目需求的逻辑,自行删除)
Photograph: function() {
var that = this
wx.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: function(res) {
that.setData({
tempfilePaths: res.tempFilePaths[0],
istake: 1,
backgroundimage: res.tempFilePaths[0],
background: ""
})
console.log(res)
if (!that.data.needUpload) {
wx.getImageInfo({
src: res.tempFilePaths[0],
success: (ress) => {
console.log(ress)
let date = util.formatTime(new Date());
let ctx = wx.createCanvasContext('firstCanvas')
let textToWidth = ress.width / 3 * 0.5
let textToHeight = ress.height / 3 * 0.9
that.setData({
canvasHeight: ress.height / 3,
canvasWidth: ress.width / 3
})
//将图片src放到cancas内,宽高为图片大小
ctx.drawImage(res.tempFilePaths[0], 0, 0, ress.width / 3, ress.height / 3)
//将声明的时间放入canvas
ctx.setFontSize(14) //注意:设置文字大小必须放在填充文字之前,否则不生效
ctx.setFillStyle('blue')
ctx.fillText(date, textToWidth, textToHeight)
// ctx.strokeText(date, ress.width, ress.height)
wx.showLoading({
title: '制作水印中...',
})
ctx.draw(false, () => {
setTimeout(()=>{
wx.canvasToTempFilePath({
canvasId: 'firstCanvas',
success: (res) => {
console.log(res)
that.setData({
backgroundimage: res.tempFilePath,
shuiyinPaths: res.tempFilePath
})
wx.hideLoading()
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success(res) {
console.log('1')
},fail(){
wx.showModal({
title: '提示',
content: '需要保存图片的权限,拒绝则无法保存',
cancelText: '拒绝',
success(res) {
if (res.confirm){
wx.openSetting({
success(res) {
if (res.authSetting["scope.writePhotosAlbum"]) {
wx.showToast({
title: '成功',
icon: 'none'
})
}
}
})
}
}
})
}
})
},
fail: (e) => {
console.log(e)
}
})
},500)
}
)
}
})
}
},
fail: function(res) {},
complete: function(res) {},
})
},