uniapp开发实现对带有动态二维码的页面实现截图保存
要求:最近工作中,uniapp开发中遇到一个问题,期望对,一个带有动态生成二维码的页面,实现截屏功能。通过webview实现的截屏功能,最后生成的图片,中间的二维码部分是空白的。
问题:实现截屏,发现只用中间的二维码部分是空白的(如图);
代码参考网上博客实现截屏:

1 saveImageByScreenshot() { 2 3 var pages = getCurrentPages(); //获取当前页面信息 4 5 var page = pages[pages.length - 1]; 6 7 var currentWebview = page.$getAppWebview(); 8 9 var bitmap = new plus.nativeObj.Bitmap('promoPage');// 将webview内容绘制到Bitmap对象中 10 11 currentWebview.draw(bitmap, function() { 12 13 console.log('截屏绘制图片成功'); 14 15 //这里我将文件名用四位随机数拼接了,不然会出现当前图片替换上一张图片只能保存一张图片的问题 16 17 let rand = Math.floor(Math.random() * 10000) 18 19 let saveUrl = '_doc/' + rand + 'a.jpg' 20 21 bitmap.save(saveUrl, {}, function(i) { 22 23 // console.log('保存图片成功:' + JSON.stringify(i)); 24 25 uni.saveImageToPhotosAlbum({ 26 27 filePath: i.target, 28 29 success: function() { 30 31 // 32 33 bitmap.clear(); //销毁Bitmap图片 34 35 uni.showToast({ 36 37 title: '保存图片成功', 38 39 mask: false, 40 41 duration: 1500, 42 43 }); 44 45 }, 46 47 }); 48 49 }, function(e) { 50 51 console.log('保存图片失败:' + JSON.stringify(e)); 52 53 }); 54 55 }, function(e) { 56 57 console.log('截屏绘制图片失败:' + JSON.stringify(e)); 58 59 });// 60 61 }
要不然,就是只能保存成一个二维码部分,

1 saveImage(e){ 2 3 const vm = this; 4 5 uni.canvasToTempFilePath({ 6 7 canvasId: 'qrcode', //promoPage promo-page 8 9 success: function(res) { 10 11 // 在H5平台下,tempFilePath 为 base64 12 13 console.log('222canvas', res.tempFilePath) 14 15 // 保存图片到相册 16 17 uni.saveImageToPhotosAlbum({ 18 19 filePath: res.tempFilePath, 20 21 success: function () { 22 23 uni.$u.toast('保存成功') 24 25 } 26 27 }); 28 29 } 30 31 }) 32 33 34 35 }
但是这个不是我想要的结果。我希望的是显示称为一个带二维码的全屏图片,研究了两天,都想要放弃了,突然脑袋中涌现了一个想法:能不能将这两个方法结合一下,先生成二维码图片,再实现截屏。然后经过了几次尝试,最终实现代码:
html部分:

1 <template> 2 3 <view class="content promo-page" id="promoPage"> 4 5 <view class="code-box"> 6 7 <view class="name">{{userInfo.nickname}}</view> 8 9 <view class="code"> 10 11 <uqrcode v-show="!isDownload" ref="uqrcode" 12 13 canvas-id="qrcode" :value="codeImg" :options="uqrcodeOption" @complete="finish"></uqrcode> 14 15 <image v-show="isDownload" :src="tempUrl"></image> 16 17 </view> 18 19 <view class="p1">扫描上方二维码即可受邀成为代理商</view> 20 21 <u-icon name="download" class="u-icon--center" size="24" color="#f56c6c" label="保存到相册" labelPos="bottom" @click="saveImage"></u-icon> 22 23 </view> 24 25 </view> 26 27 </template>
js部分:

1 <script> 2 3 export default { 4 5 data() { 6 7 return { 8 9 userInfo: {}, 10 11 uqrcodeOption:{ 12 13 margin: 10, 14 15 foregroundImageWidth: 40, 16 17 foregroundImageHeight: 40, 18 19 foregroundImagePadding: 2, 20 21 foregroundColor: '#1c5d2a', 22 23 }, 24 25 defaultHeader: '', 26 27 logo: '', 28 29 codeImg: "", 30 31 sharePicture: '', 32 33 isDownload: false, // 正在下载图片 34 35 tempUrl: '', // 临时图片路径 36 37 }; 38 39 }, 40 41 onLoad() { 42 43 let vm = this; 44 45 vm.sharePicture = config.shareEwm; 46 47 // 生产二维码 48 49 vm.userInfo = uni.getStorageSync("userInfo") 50 51 vm.getPromoCode(); 52 53 }, 54 55 methods: { 56 57 async getPromoCode() { 58 59 let path = 'https://www.baidu.com'; 60 61 this.codeImg = path; 62 63 }, 64 65 // 生成二维码回调 66 67 finish(e){ 68 69 const vm = this; 70 71 console.log("生成二维码成功", e) 72 73 if(e.success){ 74 75 //把当前画布指定区域的内容导出生成指定大小的图片,并返回文件路径 76 77 uni.canvasToTempFilePath({ 78 79 canvasId: 'qrcode', // 80 81 success: function(res) { 82 83 // 在H5平台下,tempFilePath 为 base64 84 85 vm.tempUrl = res.tempFilePath; 86 87 vm.isDownload = true; 88 89 } 90 91 }) 92 93 } 94 95 }, 96 97 // 希望实现截屏效果的截图 98 99 saveImageByScreenshot() { 100 101 var pages = getCurrentPages(); //获取当前页面信息 102 103 var page = pages[pages.length - 1]; 104 105 var currentWebview = page.$getAppWebview(); 106 107 var bitmap = new plus.nativeObj.Bitmap('promoPage');// 将webview内容绘制到Bitmap对象中 108 109 currentWebview.draw(bitmap, function() { 110 111 console.log('截屏绘制图片成功'); 112 113 //这里我将文件名用四位随机数拼接了,不然会出现当前图片替换上一张图片只能保存一张图片的问题 114 115 let rand = Math.floor(Math.random() * 10000) 116 117 let saveUrl = '_doc/' + rand + 'a.jpg' 118 119 bitmap.save(saveUrl, {}, function(i) { 120 121 // console.log('保存图片成功:' + JSON.stringify(i)); 122 123 uni.saveImageToPhotosAlbum({ 124 125 filePath: i.target, 126 127 success: function() { 128 129 // 130 131 bitmap.clear(); //销毁Bitmap图片 132 133 uni.showToast({ 134 135 title: '保存图片成功', 136 137 mask: false, 138 139 duration: 1500, 140 141 }); 142 143 this.isDownload = false; 144 145 }, 146 147 }); 148 149 }, function(e) { 150 151 console.log('保存图片失败:' + JSON.stringify(e)); 152 153 this.isDownload = false; 154 155 }); 156 157 }, function(e) { 158 159 console.log('截屏绘制图片失败:' + JSON.stringify(e)); 160 161 this.isDownload = false; 162 163 });// 164 165 }, 166 167 //保存图片到相册 168 169 saveImage(){ 170 171 // 保存图片到相册 172 173 this.saveImageByScreenshot() 174 175 }, 176 177 178 179 }, 180 181 } 182 183 </script>
css部分:

1 <style lang="scss" scoped> 2 3 .promo-page {height:calc(100vh - 44px) ;background: linear-gradient(136deg, #ef4848, #f19e48);display: flex;justify-content: center;align-items: center;} 4 5 .code-box {width: 595upx;border-radius: 15upx;background: #fff;text-align: center;padding: 20upx 30upx;box-sizing: border-box;} 6 7 .head-img { 8 9 width: 130upx; 10 11 height: 130upx; 12 13 border-radius: 50%; 14 15 margin: -65upx auto 0; 16 17 border: 2px solid #eee; 18 19 background: #fff; 20 21 display: block; 22 23 overflow: hidden; 24 25 } 26 27 28 29 .name { 30 31 font-size: 36upx; 32 33 margin-top: 20upx; 34 35 font-weight: 600; 36 37 } 38 39 40 41 .code-str { 42 43 font-size: 28upx; 44 45 margin-top: 10upx; 46 47 } 48 49 50 51 .code { 52 53 width: 385upx; 54 55 height: 385upx; 56 57 margin: 25upx auto; 58 59 border: 1px solid #eee; 60 61 display: flex; 62 63 align-items: center; 64 65 justify-content: center; 66 67 } 68 69 70 71 .p1 { 72 73 font-size: 28upx; 74 75 margin: 50upx 0 10upx; 76 77 } 78 79 80 81 .p2 { 82 83 font-size: 25upx; 84 85 color: #aaa; 86 87 margin-top: 10upx; 88 89 } 90 91 92 93 .logo { 94 95 width: 211upx; 96 97 height: 73upx; 98 99 // margin-top: 30upx; 100 101 position: absolute; 102 103 bottom: 30upx; 104 105 } 106 107 108 109 image { 110 111 width: 100%; 112 113 height: 100%; 114 115 } 116 117 118 119 </style>
最终效果图:
原因:因为在uniapp中截屏并不能截取到canvas标签的内容,却可以实现image标签的截图。实现思路:
- 先使用uqrcode生成二维码;
- 使用uqrcode的回调函数complete,判断生成二维码成功后,将canvas转成临时路径,并且将canvas标签隐藏。将临时路径赋值给一个image标签;
- 点击保存图片,再调用截屏方法,即可实现带二维码的截屏图片。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类