> 技术文档 > UniApp+Vue3微信小程序二维码生成、转图片、截图保存整页_vue生成二维码并保存图片

UniApp+Vue3微信小程序二维码生成、转图片、截图保存整页_vue生成二维码并保存图片


二维码生成工具使用@uqrcode/js,版本4.0.7
官网地址:uQRCode 中文文档(不建议看可能会被误导)
本项目采用了npm引入方式,也可通过插件市场引入,使用上会略有不同


准备工作:
安装:pnpm add @uqrcode/js
引入:import UQRCode from \'@uqrcode/js/uqrcode\'


二维码生成及转图片逻辑:

  // 生成二维码const generateWXQRCode = async () => { const query = uni.createSelectorQuery(); query.select(\'#qrcodeCanvas\') .fields({ node: true, size: true }, () => {}) .exec(async (res) => { if (!res[0]?.node) { console.error(\'未找到二维码Canvas节点\'); return; } const canvas = res[0].node; const ctx = canvas.getContext(\'2d\'); const { width, height } = res[0]; // 设置 canvas 的绘制尺寸(避免模糊) canvas.width = width; canvas.height = height; // 创建二维码实例 const qrcode = new UQRCode({ data: `111111`, size: Math.min(width, height), canvasContext: ctx }); // 绘制二维码 await qrcode.make(); await qrcode.draw(); // 获取base64并转为在线url const fileRes: any = await base64ToTempFile({ image: canvas.toDataURL() }) // 转为临时url uni.downloadFile({ url: fileRes.data.fileUrl, success: (res) => { pageData.qrCodePath = res.tempFilePath } }); });};

页面绘制:
 

  const screenWidth = ref(300)const screenHeight = ref(400)// 保存当前页面为图片const takeScreenshot = async () => { try { // 1. 获取系统信息 const systemInfo = await uni.getSystemInfo() screenWidth.value = systemInfo.screenWidth screenHeight.value = systemInfo.screenHeight // 2. 设置canvas尺寸(考虑设备像素比) const dpr = systemInfo.pixelRatio || 1 const canvasWidth = Math.min(screenWidth.value, 750) const canvasHeight = Math.min(screenHeight.value, 1334) const rpxToPx = screenWidth.value / 750 // 3. 获取canvas上下文 const canvasContext = uni.createCanvasContext(\'screenshotCanvas\') // 4. 绘制白色背景(确保有内容) canvasContext.setFillStyle(\'#FFFFFF\') canvasContext.fillRect(0, 0, canvasWidth, canvasHeight) // 5. 绘制背景图(使用绝对路径) const bgPath = \'/subPages/static/qrcode-bg.png\' // 确保图片存在于此路径 try { canvasContext.drawImage(bgPath, 0, 0, canvasWidth, canvasHeight) } catch (err) { console.error(\'背景图加载失败:\', err) // 使用备用颜色 canvasContext.setFillStyle(\'#F0F0F0\') canvasContext.fillRect(0, 0, canvasWidth, canvasHeight) } // 6. 绘制文本内容 const fontSizeTitle = 72 * rpxToPx const fontSizeDesc = 32 * rpxToPx const centerX = canvasWidth / 2 // 标题 canvasContext.setFontSize(fontSizeTitle) canvasContext.setFillStyle(\'#000000\') // 改为黑色确保可见 canvasContext.setTextAlign(\'center\') const displayText = pageData.name?.length > 7 ? pageData.name.substring(0, 6) + \'...\' : pageData.name canvasContext.fillText(displayText, centerX, 260 * rpxToPx) // 副标题 canvasContext.setFontSize(fontSizeDesc) canvasContext.fillText(\'邀请您加入车队\', centerX, 320 * rpxToPx) // 绘制二维码 const qrSize = 200; const qrX = (canvasWidth - qrSize) / 2; const qrY = 480 * rpxToPx; canvasContext.drawImage(pageData.qrCodePath, qrX, qrY, qrSize, qrSize); // 失效时间 canvasContext.setFillStyle(\'#000000\') canvasContext.fillText( `${pageData.selectedTime} 23:59:59后失效`, centerX, 920 * rpxToPx ) // 7. 执行绘制(关键修改) await new Promise((resolve, reject) => { canvasContext.draw(true, () => { setTimeout(() => { // 检查Canvas内容 console.log(\'Canvas绘制完成\') resolve() }, 500) // 增加延迟确保渲染完成 }) }) // 8. 生成临时文件 const { tempFilePath } = await uni.canvasToTempFilePath({ canvasId: \'screenshotCanvas\', quality: 1, // 最高质量 width: canvasWidth * dpr, // 考虑DPI height: canvasHeight * dpr }) // 9. 保存到相册 await uni.saveImageToPhotosAlbum({ filePath: tempFilePath }) uni.showToast({ title: \'保存成功\', icon: \'success\' }) } catch (err) { console.error(\'截图失败:\', err) uni.showToast({ title: \'保存失败: \' + (err.errMsg || \'未知错误\'), icon: \'none\', duration: 3000 }) }}