关于小程序实现图片合成和保存功能
1.准备好两张图片,用于合成,使用网络地址图片要注意等它加载完成后才能成功绘制到画布上。
2.在wxml文件中写入以下代码,注意:若使用display:none隐藏画布,在安卓端正常,但在IOS端会保存不了。
<canvas id="myCanvas" type="2d" style="left:9000px;position:fixed;" />
3.js文件代码如下
1)在画布上绘制图片和文字
async onLoad(options) {
var that=this
var height=wx.getSystemInfoSync().screenHeight
var winWidth=wx.getSystemInfoSync().windowWidth
this.setData({height:height*(750/winWidth)})
var canvas=await new Promise(function(resolve,reject) {
wx.createSelectorQuery()
.select('#myCanvas') // 在 WXML 中填入的 id
.fields({ node: true, size: true })
.exec((res) => {
// Canvas 对象
const canvas = res[0].node
// 渲染上下文
const ctx = canvas.getContext('2d')
wx.getImageInfo({//获取背景图图片信息
src: 'https://xxx/xxx.png',
success(res){
const img_w=res.width
const img_h=res.height
// Canvas 画布的实际绘制宽高
const width = img_w
const height = img_h
// 初始化画布大小
const dpr = 750 / wx.getSystemInfoSync().windowWidth;
canvas.width = width*dpr
canvas.height = height*dpr
ctx.scale(dpr, dpr)
that.setData({
img_w:img_w,
img_h:img_h})
resolve(canvas)
}
})
})
})
var ctx=canvas.getContext('2d')
const image = canvas.createImage()//背景图
const code_img = canvas.createImage()//接口返回的二维码图片
image.src = 'https://xxx/haibao.png'+'?t='+Date.now()// 图片路径添加随机参数,防止缓存问题导致image.onload不能再次触发
let mainImg= await new Promise((resolve, reject) => {//等待图片加载完成
image.onload = () => {
resolve(image)
}
image.onerror = (e) => {
reject(e)
}
})
//绘制背景图
ctx.drawImage(mainImg, 0, 0,that.data.img_w,that.data.img_h)
// 设置二维码图片src
code_img.src = 'https://xxx/code.png'
code_img.onload = () => {
// 将二维码图片绘制到背景图上
ctx.drawImage(code_img,66,890,124,124)
//绘制文本
ctx.font = "20px normal"; //设置字体大小,默认10
ctx.fillStyle = '#685b66'; //文字颜色:默认黑色
var str='测试一下绘制换行文字测试一下绘制换行文字~~~~~~~~~'
var lineWidth = 0;
var leftWidth =250;
var maxWidth=256 //每一行文字最大长度
var initHeight=952//刚开始绘制文字时的高度位置
var lastSubStrIndex = 0; //每次开始截取的字符串的索引
for (let i = 0; i < str.length; i++) {
lineWidth += ctx.measureText(str[i]).width; //计算文字宽度
if (lineWidth > maxWidth) {
ctx.fillText(str.substring(lastSubStrIndex, i), leftWidth, initHeight); //绘制截取部分
initHeight += 30; //设置下一行的高度位置
lineWidth = 0;
lastSubStrIndex = i;
}
if (i == str.length - 1) { //绘制剩余部分
ctx.fillText(str.substring(lastSubStrIndex, i + 1), leftWidth, initHeight);
}
}
that.setData({canvas:canvas})//绘制完成保存画布
}
code_img.onerror = (e) => {
reject(e,'code_img加载出错')
}
}
2)保存图片到相册(注意:在保存图片时需判断图片是否绘制完成,否则可能保存失败,可设置标志进行判断,这里就不展示了)
saveFn(){
var that=this
wx.showLoading({
title: '图片生成中',
})
wx.canvasToTempFilePath({
canvas: that.data.canvas,
success: res => {
// 生成的图片临时文件路径
var url=res.tempFilePath
wx.saveImageToPhotosAlbum({
filePath: url,
success(res) {
wx.hideLoading()
wx.showToast({
title: '图片已保存到相册',
icon:'none'
})
},
fail: function (err) {
wx.hideLoading()
if (
err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" ||
err.errMsg === "saveImageToPhotosAlbum:fail auth deny" ||
err.errMsg === "saveImageToPhotosAlbum:fail authorize no response"
){
wx.showModal({
content: '需要授权保存到相册',
showCancel: false,
confirmText: '好的',
confirmColor: '#333',
success: function (res) {
if (res.confirm) {
wx.openSetting({
success(settingdata) {
if (settingdata.authSetting['scope.writePhotosAlbum']) {
wx.showToast({
title: '获取权限成功,请重新点击生成图片',
icon:'none'
})
} else {
wx.showToast({
title: '获取权限失败,无法保存图片,请重新授权',
icon:'none'
})
}
}
})
}
},
fail: function (res) {
wx.hideLoading()
}
})
}
}
})
},
fail:function (res2) {
console.log(res2)
},
})
}