uniapp开发实现对带有动态二维码的页面实现截图保存

发布时间 2023-11-30 11:20:32作者: 海底流

要求:最近工作中,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 }
View Code

要不然,就是只能保存成一个二维码部分,

 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 }
View Code

但是这个不是我想要的结果。我希望的是显示称为一个带二维码的全屏图片,研究了两天,都想要放弃了,突然脑袋中涌现了一个想法:能不能将这两个方法结合一下,先生成二维码图片,再实现截屏。然后经过了几次尝试,最终实现代码:

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>
View Code

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>
View Code

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>
View Code

最终效果图:

原因:因为在uniapp中截屏并不能截取到canvas标签的内容,却可以实现image标签的截图。实现思路:

  1. 先使用uqrcode生成二维码;
  2. 使用uqrcode的回调函数complete,判断生成二维码成功后,将canvas转成临时路径,并且将canvas标签隐藏。将临时路径赋值给一个image标签;
  3. 点击保存图片,再调用截屏方法,即可实现带二维码的截屏图片。