uniApp小程序保存定制二维码到本地(V3)
这里的二维码组件用的 uv-ui 的二维码 可以按需引入
QRCode 二维码 | 我的资料管理-uv-ui 是全面兼容vue3+2、nvue、app、h5、小程序等多端的uni-app生态框架
<uv-qrcode ref="qrcode" :size="280" :value="payCodeUrl"></uv-qrcode><button type="primary" block @click="saveCode">保存收款码</button>const payCodeUrl = 'https://xxxx/xxx.jpg'// 获取proxyconst { proxy } = getCurrentInstance()const wxPayIconUrl = "https://xxx.cn/upload/wxPay.png"; // 微信支付图标const zfbPayIconUrl = "https://xxx.cn/upload/zfbPay.png"; // 支付宝支付图标const saveQrCode = () => {uni.showLoading({ title: '正在生成图片...', mask: true })console.log('开始生成图片...')return new Promise((resolve, reject) => {// 这里用到的proxy 其实和v2的this 是一样的 我这么写才会显示const ctx = uni.createCanvasContext('qrCanvas', proxy)console.log('Canvas上下文已创建')ctx.setFillStyle('#FFFFFF')ctx.fillRect(0, 0, 600, 800)console.log('背景绘制完成')// 先绘制图标 如果没有图表 可以越过这里 直接去写.then后面的Promise.all([new Promise((resolve, reject) => {uni.downloadFile({url: wxPayIconUrl,success: resolve,fail: reject})}),new Promise((resolve, reject) => {uni.downloadFile({url: zfbPayIconUrl,success: resolve,fail: reject})})]).then(([wxRes, zfbRes]) => {qrcode.value.toTempFilePath({success: (res) => {const qrCodePath = res.tempFilePathconsole.log('二维码临时文件获取成功:', qrCodePath)// 处理Base64数据const [, format, base64Data] = /data:image\/(\w+);base64,(.+)$/.exec(qrCodePath) || []if (!base64Data) {console.error('无法解析Base64数据')return reject(new Error('无法解析Base64数据'))}const tempFilePath = `${wx.env.USER_DATA_PATH}/qrcode_temp.${format || 'png'}`uni.getFileSystemManager().writeFile({filePath: tempFilePath,data: uni.base64ToArrayBuffer(base64Data),encoding: 'binary',success: () => {console.log('Base64 转换为临时文件成功:', tempFilePath)uni.getImageInfo({src: tempFilePath,success: (qrRes) => {console.log('二维码已绘制到Canvas')ctx.setFillStyle('#e9edf5')ctx.fillRect(0, 0, 600, 800)ctx.drawImage(qrRes.path, 100, 200, 400, 400)// 绘制标题ctx.setTextAlign('center')ctx.setFontSize(32)ctx.setFillStyle('#000000')ctx.fillText('扫码支付', 300, 120)// 绘制金额ctx.setFontSize(36)ctx.setFillStyle('#1989fa')ctx.fillText(`¥${amount.value}`, 300, 180)// 绘制支付图标ctx.drawImage(wxRes.tempFilePath, 183, 650, 60, 60) // 微信图标ctx.drawImage(zfbRes.tempFilePath, 345, 650, 60, 60) // 支付宝图标// 绘制支付方式文字ctx.setFontSize(20)ctx.setFillStyle('#666666')ctx.fillText('微信支付', 220, 740)ctx.fillText('支付宝支付', 380, 740)// 这里的ctx.draw 为什么设置false 我也不理解 有没有大神给讲下 我设置为false就可以正常保存图片了 设置为true就不执行 加setTimeout也不行ctx.draw(false, () => {console.log('Canvas绘制完成')uni.canvasToTempFilePath({canvasId: 'qrCanvas',destWidth: 600,destHeight: 800,quality: 1,success: (res) => {console.log('Canvas临时文件生成成功:', res)uni.saveImageToPhotosAlbum({filePath: res.tempFilePath,success: () => {console.log('图片保存成功')uni.hideLoading()uni.showToast({ title: '保存成功', icon: 'success' })resolve()},fail: (err) => {console.error('保存失败:', err)uni.hideLoading()uni.showToast({ title: '保存失败,请检查权限', icon: 'none' })reject(err)}})},fail: (err) => {console.error('转换图片失败:', err)uni.hideLoading()uni.showToast({ title: '生成图片失败', icon: 'none' })reject(err)}},proxy)})},fail: (err) => {console.error('获取临时文件图片信息失败:', err)uni.hideLoading()uni.showToast({ title: '获取图片信息失败', icon: 'none' })reject(err)}})},fail: (err) => {console.error('Base64 转换临时文件失败:', err)uni.hideLoading()uni.showToast({ title: '图片处理失败', icon: 'none' })reject(err)}})},fail: (err) => {console.error('获取二维码临时文件失败:', err)uni.hideLoading()uni.showToast({ title: '获取二维码失败', icon: 'none' })reject(err)}})}).catch(err => {console.error('下载图标失败:', err)uni.hideLoading()uni.showToast({ title: '下载支付图标失败', icon: 'none' })reject(err)})})}