業務需求:選擇圖片添加水印,并保存,或上傳
技術要點:畫布,圖片選擇、上傳、保存
首先需要一個圖片容器和一個畫布
<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) {},
})
},