1. canvas中嵌入图片问题
曾经天真的使用base64自娱自乐许久,最后在真机运行时傻了眼,最后发现只能使用本地临时图片或本地图片来绘制canvas。
本地图片可以直接放置(项目中的图片)
// 本地图片可以直接放置
ctx.drawImage('/packageA/assets/img/poster/poster_bg.png', 0, 0, 350, 500, 0, 0
base64需要转换为本地图片(如后台返回的base64格式图片或二维码等)
function base64ToWxfile(base64,fileName) {
// 生成的临时路径
const path = wx.env.USER_DATA_PATH + "/"+ fileName
return new Promise((reslove, reject) => {
wx.getFileSystemManager().writeFile({
filePath: path,
data: base64,
encoding: 'base64',
success: (res) => {
reslove(path)
},
fail: (err) => {
reject(err)
}
})
})
}
// res为后台返回的base64图片流
const qrCode = res
// 将base64转为微信临时文件路径
base64ToWxfile(qrCode, "test.png").then(path=>{
ctx.drawImage(path, 0, 0, 350, 500, 0, 0)
})
线上URL需要转为Base64后存为本地文件
比如当我们从服务器获取的微信头像需要嵌入到canvas时,微信头像的url是一串链接,我们将需要将链接转为base64后再转为本地临时文件。
function urlTobase64(url, ishead = false) {
return new Promise((reslove, reject) => {
wx.request({
url: url,
responseType: 'arraybuffer', //最关键的参数,设置返回的数据格式为arraybuffer
success: res => {
//把arraybuffer转成base64
let base64 = wx.arrayBufferToBase64(res.data);
//不加上这串字符,在页面无法显示
base64 = (ishead ? 'data:image/jpeg;base64,' : '') + base64
reslove(base64)
}
})
})
}
function base64ToWxfile(base64,fileName) {
const path = wx.env.USER_DATA_PATH + "/"+ fileName
return new Promise((reslove, reject) => {
wx.getFileSystemManager().writeFile({
filePath: path,
data: base64,
encoding: 'base64',
success: (res) => {
reslove(path)
},
fail: (err) => {
reject(err)
}
})
})
}
const url = '...'
// 将url转为base64
base64ToWxfile(url).then(base64=>{
// 将base64转为微信临时文件路径
base64ToWxfile(base64, "test.png").then(path=>{
ctx.drawImage(path, 0, 0, 350, 500, 0, 0)
})
})
2. 关于头像的圆形剪裁
微信返回的头像是方形的,放在海报上着实不好看,所以需要我们自己用canvas做简单的裁剪
// 头像已转为临时文件路径
const avatar = '...'
// 我们需要在头像裁剪前将所有内容放置好
const ctx = wx.createCanvasContext('myCanvas')
// 设置画布背景
ctx.rect(0, 0, 350, 450)
ctx.setFillStyle('#fff')
ctx.fill()
ctx.clip()
// 设置文字
ctx.font = 'normal bold 24px Monospaced Number,Chinese Quote,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif'
// 文字居中(需要配合设置文字所在位置为画布的中间点)
ctx.textAlign = 'center'
ctx.setFillStyle('#000')
// 所在位置为中间点,可以居中,350/2 = 175
ctx.fillText(user.userName, 175, 180)
ctx.font = 'normal normal 12px Monospaced Number,Chinese Quote,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif'
ctx.fillText('邀请您加入「' + user.companyName + '」', 175, 208)
ctx.setFillStyle('#90959F')
ctx.fillText('长按图片扫码添加', 175, 420)
// 最后做裁剪否则画布只显示裁剪区域
// 开始路径
ctx.beginPath();
// 画出一个圆 y轴、x轴、半径、起始角度、结束角度、顺逆时针
ctx.arc(175, 90, 50, 0, Math.PI * 2, false);
// 结束路径
ctx.closePath()
// 设置圆的背景色为白色
ctx.setFillStyle('#fff')
ctx.fill()
ctx.clip()
// 放置图片
ctx.drawImage(avatarUrl, 125, 40, 100, 100, 0, 0)
ctx.draw()
ctx.beginPath()
ctx.draw(true);
3. 关于小程序中canvas转为图片保存到手机相册
// canvas转为本地临时文件
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: 350,
height: 450,
canvasId: 'myCanvas',
success: function(res) {
let img = res.tempFilePath
// 保存至本地,此时会弹窗要求用户授权
wx.saveImageToPhotosAlbum({
filePath: img,
success(json) {
app.toast('成功保存', 'success')
},
fail(err) {
app.toast('保存失败', err)
}
})
},
fail(err) {
console.log(err)
}
})