最近写了需求 用 canvas 保存 2 张图片叠在一起 并保存手机相册 先上代码
javascript
<wd-button type="primary" class="download-btn" @click="downloadImage">下载图片</wd-button>
<canvas
canvas-id="mergeCanvas"
style="position: absolute; left: -9999px; width: 300px; height: 400px"
width="300"
height="300"
></canvas>
//这里的canvas的dom元素 如果不想展示的话 可以用上面的style
// 下载图片
const downloadImage = async () => {
uni.getSetting({
success(res) {
console.log(res.authSetting, 'res.authSetting')
if (!res.authSetting['scope.writePhotosAlbum']) {
uni.authorize({
scope: 'scope.writePhotosAlbum',
success() {
saveImg()
},
})
} else {
saveImg()
}
},
})
}
// 合并图片方法
const mergeImages = async () => {
try {
return new Promise((resolve, reject) => {
const ctx = uni.createCanvasContext('mergeCanvas', proxy) // 使用 proxy
// 获取底图信息
uni.getImageInfo({
src: 'https://xxx.com',
success: (baseRes) => {
const width = 300
const height = 400
// 绘制底图
ctx.drawImage(baseRes.path, 0, 0, width, height)
// 获取叠加图信息
uni.getImageInfo({
src: data.deviceInfo.image,
success: (overlayRes) => {
// 绘制叠加图
ctx.drawImage(overlayRes.path, 55, 105, 187, 187)
// 添加码牌编号
ctx.setFontSize(16) // 设置字体大小
ctx.setFillStyle('black') // 设置字体颜色
ctx.fillText(`LSF${data.deviceInfo.merchantCodeId}`, width * 0.32, height * 0.74) // 在底部添加码牌编号
// 执行绘制操作
setTimeout(() => {
ctx.draw(false, () => {
uni.canvasToTempFilePath({
canvasId: 'mergeCanvas',
success: (res) => {
resolve(res.tempFilePath)
},
fail: (err) => {
reject(err)
},
})
})
}, 100)
},
fail: (err) => {
console.error('叠加图加载失败:', err)
reject(err)
},
})
},
fail: (err) => {
console.error('底图加载失败:', err)
reject(err)
},
})
})
} catch (error) {
console.log(error, 'error')
}
}
const saveImg = async () => {
try {
uni.showLoading({ title: '图片保存中...' })
const mergedImagePath = await mergeImages()
// 保存图片到相册
uni.saveImageToPhotosAlbum({
filePath: mergedImagePath,
success: () => {
uni.showToast({ title: '保存成功', icon: 'success' })
},
fail: (err) => {
console.log(err, 'err')
if (err.errMsg === 'saveImageToPhotosAlbum:fail auth deny') {
uni.openSetting({
success(settingdata) {
if (settingdata.authSetting['scope.writePhotosAlbum']) {
uni.showToast({
title: '您已授权成功,请重新保存',
icon: 'success',
duration: 2000,
})
} else {
uni.showToast({
title: '尚未授权,无法保存海报',
icon: 'none',
duration: 2000,
})
}
},
})
}
},
complete: () => {
uni.hideLoading() // 确保在操作完成后隐藏加载提示
},
})
} catch (error) {
console.log(error)
uni.showToast({ title: '图片生成失败', icon: 'none' })
// uni.hideLoading() // 确保在捕获错误时也隐藏加载提示
}
}
代码看起来没问题 但上线后就下载不了 体验版可以下载 找了很久 发现 需要去设置一下微信小程序的用户隐私保护指引

这里显示已更新就行 没有处理的 需要先处理一下 才能发起权限