主要代码
const [base64Img, setBase64Img] = useState('')
const [qrCodeUrl, setQrCodeUrl] = useState<string>('')
const imgToCanvas = useCallback(async () => {
const canvas = wx.createOffscreenCanvas({type: '2d'})
const context = canvas.getContext('2d')
const img = canvas.createImage()
img.src = sharePaper
await new Promise((resolve) => (img.onload = resolve));
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 0, 0, img.width, img.height)
const qrImg = wx.createOffscreenCanvas({type: '2d'}).createImage()
const qrcode = await downloadFile({
url: qrCodeUrl
})
qrImg.src = qrcode
await new Promise((resolve) => (qrImg.onload = resolve));
context.drawImage(qrImg, 60, img.height - qrImg.height + 60, qrImg.width * 0.7, qrImg.height * 0.7)
// 到此流产
context.draw(true, () => {
wx.canvasToTempFilePath({
canvas,
}).then(res => {
setTpmPath(res.tempFilePath)
})
})
// 流产结束
// 下面返回的是base64格式的图片
return context.canvas.toDataURL('image/png')
},[qrCodeUrl])
useEffect(() => {
imgToCanvas().then(url => setBase64Img(url));
}, [imgToCanvas]);
流产开始到结束的意思是那段代码无效,context.draw被报undefined,百度了大半天,看到下面的话快哭了
只能用context.canvas.toDataURL('image/png')转成base64格式,但是对我下面将图片保存在相册太难了,因为
authorize({ scope: 'scope.writePhotosAlbum' })
.then(() => {
saveImageToPhotosAlbum({
filePath: tpmPath,
// filePath: wx.env.USER_DATA_PATH + '/pic' + number + '.png',
success (res: TaroGeneral.CallbackResult) {
showToast({ title: '分享图已成功保存到相册', icon: 'none' })
},
fail (res: TaroGeneral.CallbackResult) {
showToast({ title: '生成分享图失败,请重试', icon: 'none' })
},
complete (res: TaroGeneral.CallbackResult) {
hideLoading()
}
})
})
.catch(() => void showToast({ title: '请授权保存图片权限以保存分享图', icon: 'none' }))
因为saveImageToPhotosAlbum需要合成图片的临时路径filePath,也就是我要将合成base64图片格式转成图片格式并保存到本地,那么就要做文件的读写操作,
const save = getFileSystemManager();
const number = Math.random();
// 点击保存图片
const saveImageClickHandler = () => {
showLoading({ title: '生成分享图...', mask: true })
save.writeFile({
filePath: wx.env.USER_DATA_PATH + '/pic' + number + '.png',
data: base64Img,
encoding: 'base64',
success: res => {
authorize({ scope: 'scope.writePhotosAlbum' })
.then(() => {
saveImageToPhotosAlbum({
// filePath: tpmPath,
filePath: wx.env.USER_DATA_PATH + '/pic' + number + '.png',
success (res: TaroGeneral.CallbackResult) {
showToast({ title: '分享图已成功保存到相册', icon: 'none' })
},
fail (res: TaroGeneral.CallbackResult) {
showToast({ title: '生成分享图失败,请重试', icon: 'none' })
},
complete (res: TaroGeneral.CallbackResult) {
hideLoading()
}
})
})
.catch(() => void showToast({ title: '请授权保存图片权限以保存分享图', icon: 'none' }))
},
fail: err => {
console.log(err)
}
})
}
看到这你心里是不有一万只草泥马骂到博主;离线太坑爹了,canvas导出图片只能是base64,而不是本地路径;如果单纯的将两张图合在一起,可以用离线;如果后续要保存相册操作,最好不用离线。关于不用离线的看我写的这个:https://www.cnblogs.com/wangwenhui/p/16071095.html