canvas生成海报并保存到手机

强烈建议大家不要入uni-app这个陨石坑…

  1. 网络图片必须保存到本地 uni.getImageInfo()或者uni.downloadFile(),推荐前者,不要在onLoad生命周期里面下载地址,必须放在生成二维码的回调里面;
  2. 网络图片必须是白名单里面,协议必须是https;
  3. 画图保存CanvasContext.drawImage必须要在CanvasContext.draw(boolean reserve, function callback)的回调函数里面;

演示demo:

生成二维码组件github地址:https://github.com/q310550690/uni-app-qrcode

html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<template>
<view class="content">
<button type="primary" @tap="saveToAlbum">保存</button>
<view class="post">
<tki-qrcode
ref="qrcode"
:val="val"
:size="200"
background="#fff"
foreground="#000"
pdground="#000"
:onval="false"
:loadMake="false"
@result="qrR"
:show="false"
></tki-qrcode>
<view class="wrapper"><canvas style="height: 100%;width: 100%;backgroundColor: #FFFFFF" canvas-id="firstCanvas"></canvas></view>
</view>
</view>
</template>

javascript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<script>
import tkiQrcode from '@/components/qrcode/tki-qrcode.vue';
export default {
name: 'canvas-drawer',
components: {
tkiQrcode
},
data() {
return {
val: 'https://www.baidu.com',
cover: 'https://inews.gtimg.com/newsapp_bt/0/2543905722/1000'
};
},
onLoad() {},
methods: {
qrR(path) {
let that = this;
this.qr_path = path;
let system_info = uni.getSystemInfoSync();
let ctx = uni.createCanvasContext('firstCanvas');
uni.getImageInfo({
src: that.cover,
success(res) {
console.log(res.path);
ctx.drawImage(res.path, 0, 0, 375, uni.upx2px(1020));
let linearGrad = ctx.createLinearGradient(0, 0, 800, 0);
linearGrad.addColorStop('0.25', '#8b00d2');
linearGrad.addColorStop('0.5', '#003fb3');
linearGrad.addColorStop('0.75', '#ff3ef0');
ctx.fillStyle = '#FFFFFF';
ctx.fillRect(uni.upx2px(500), uni.upx2px(790), uni.upx2px(200), uni.upx2px(210));
ctx.drawImage(path, uni.upx2px(520), uni.upx2px(800), uni.upx2px(160), uni.upx2px(160));
ctx.font = '13px Arial';
ctx.fillStyle = '#000';
ctx.fillText('长按保存二维码', uni.upx2px(508), uni.upx2px(990));
ctx.draw(false, () => {
uni.canvasToTempFilePath({
x: 0,
y: 0,
width: 375,
height: uni.upx2px(1020),
destWidth: 375,
destHeight: uni.upx2px(1020),
canvasId: 'firstCanvas',
success: function(res) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: function() {
console.log('save success');
}
});
},
fail(e) {
console.log(e);
uni.showToast({
title: '生成海报失败',
icon: 'none'
});
}
});
});
},
fail(error) {
console.log(error);
}
});



},
saveToAlbum() {
this.$refs.qrcode._makeCode();
}
}
};
</script>

style

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<style lang="scss">
.post {
height: 100%;
background-color: #f4f4f4;

.wrapper {
height: 1020rpx;
display: flex;
justify-content: center;
align-items: center;
margin-top: 50upx;
}
}
</style>

效果图: