效果图
引用
想直接看效果的可以不传值
<QrcodePoster style="width: 100%;" ref="poster"></QrcodePoster>
点击按钮上绑定点击事件代码如下
//分享海报
sharePoster() {//获取带参数二维码并传递this.is_show_model = false;// this.$refs.poster.showCanvas('../../static/healthPunch/code.jpg');this.$refs.poster.showCanvas();
}
下面是海报(页面 QrcodePoster)组件的全部代码,可以在这个基础上写你想要的,因为这个保存图片之后清晰度正常。
<template><view class="content" v-if="isShow" @click.stop="isShow=false"><canvas :style="'width:'+canvasW+'px;'+'height:'+canvasH+'px;'" canvas-id="mycanvas" id="mycanvas"></canvas><view><view class="save-btn" @click.stop="saveImage"><imagesrc="https://yiben01.oss-cn-hangzhou.aliyuncs.com/img/88774b97dd59933a6d5121ca7ba6718c7c6603bd_100.png"mode=""></image><text>保存到相册</text></view></view></view>
</template><script>export default {props: {headerImg: {default: 'https://yiben01.oss-cn-hangzhou.aliyuncs.com/img/e9c557905980d0f7d4ccaf280af1ba73c4b92a5c_52.jpg',type: String},abImg: {type: String,default: '../static/code.jpg'},week: {default: '星期四',type: String},date: {default: '08',type: String},year: {default: '08.2022',type: String},day: {default: '25',type: String},realName: {default: '张七七',type: String},color: '#ffffff',maskImg: {type: String,default: '../static/mask.png'}},data() {return {canvasW: 0,canvasH: 0,ctx: null,isShow: false,qrcode: '',system_info: '',codeimage: require('../static/code.jpg')}},mounted() {},onReady() {this.ctx = uni.createCanvasContext('mycanvas', this)},methods: {//显示showCanvas(qrcode) {this.isShow = truethis.qrcode = qrcodethis.__init()},async __init() {uni.showLoading({title: '加载中...',mask: true})var system_info = uni.getSystemInfoSync(); //屏幕宽高this.ctx.beginPath();this.ctx.save(); // 先保存状态 已便于画完圆再用//获取标题图片let headerImg = await this.getImageInfo(this.headerImg)var width = system_info.screenWidth;let hW = system_info.windowHeight / system_info.windowWidth >= 1.7 ? (width * 0.8) : (width * 0.7);let hH = (hW * headerImg.height / headerImg.width);let leftwidth = (width - hW) / 2this.canvasW = hW;this.canvasH = hH;//设置画布大小this.ctx.fillRect(leftwidth, 40, this.canvasW, this.canvasH)//绘制标题图this.drawRoundImg(this.ctx, headerImg.path, 0, 0, parseFloat(hW) + 1,parseFloat(hH) + 1, 0)// 遮罩层this.drawRoundImg(this.ctx, this.maskImg, 0, (this.canvasH - this.canvasH / 2 / 2), this.canvasW,parseFloat(this.canvasH / 2 / 2) + 1, 0)// 二维码this.drawRoundImg(this.ctx, this.abImg, (this.canvasW / 2 + this.canvasW / 2 / 2), (this.canvasH - this.canvasH / 2 / 2 / 2 / 2 / 2 - 55), 55, 55, 55 / 2)//绘制标题this.ctx.setFontSize(8); //设置标题字体大小this.ctx.setFillStyle(this.color); //设置标题文本颜色this.ctx.font = 'normal bold 10px sans-serif';// this.ctx.fillText(this.week, 21, 115)this.ctx.fillText(this.week, uni.upx2px(54), this.canvasH / 2 / 2 + 8)this.ctx.setFontSize(12);this.ctx.setFillStyle(this.color);this.ctx.fillText(this.year, uni.upx2px(54), this.canvasH / 2 / 2 - 12)this.ctx.setFontSize(40);this.ctx.setFillStyle(this.color);this.ctx.fillText(this.date, uni.upx2px(54), this.canvasH / 2 / 2 - 38)this.ctx.setFontSize(12);this.ctx.setFillStyle('#969696');this.ctx.textAlign = "center"; //文字居中this.ctx.fillText('长按识别二维码', hW / 2, 350)this.ctx.font = 'normal bold 16px sans-serif';this.ctx.setFillStyle('#FFFFFF');// 昵称 this.ctx.fillText(this.realName, uni.upx2px(54), this.canvasH - this.canvasH / 2 / 2 / 2 / 2 / 2 - 30)this.ctx.font = '12px normal';this.ctx.setFillStyle('#FFFFFF');this.ctx.fillText('坚持打卡', uni.upx2px(54), this.canvasH - this.canvasH / 2 / 2 / 2 / 2 / 2 - 10)this.ctx.font = 'normal bold 18px sans-serif';this.ctx.setFillStyle('#FFFFFF');this.ctx.fillText(this.day, this.ctx.measureText('坚持打卡').width+uni.upx2px(54), this.canvasH - this.canvasH / 2 / 2 /2 / 2 / 2 - 10)this.ctx.font = '12px normal';this.ctx.setFillStyle('#FFFFFF');this.ctx.fillText('天', 135, this.canvasH - this.canvasH / 2 / 2 / 2 / 2 / 2 - 10)this.ctx.draw()uni.hideLoading();},//带圆角图片drawRoundImg(ctx, img, x, y, width, height, radius) {ctx.beginPath()ctx.save()// 左上角ctx.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 1.5)// 右上角ctx.arc(x + width - radius, y + radius, radius, Math.PI * 1.5, Math.PI * 2)// 右下角ctx.arc(x + width - radius, y + height - radius, radius, 0, Math.PI * 0.5)// 左下角ctx.arc(x + radius, y + height - radius, radius, Math.PI * 0.5, Math.PI)// ctx.stroke()ctx.clip()ctx.drawImage(img, x, y, width, height);ctx.restore()ctx.closePath()},//获取图片getImageInfo(imgSrc) {return new Promise((resolve, reject) => {uni.getImageInfo({src: imgSrc,success: (image) => {resolve(image);},fail: (err) => {reject(err);}});});},//保存图片到相册saveImage() {let that = thisuni.canvasToTempFilePath({fileType: 'jpg',canvasId: 'mycanvas',quality: 1,complete: (res) => {uni.saveImageToPhotosAlbum({filePath: res.tempFilePath,success(res) {uni.showToast({title: '已保存到相册',icon: 'success',duration: 2000})setTimeout(() => {that.isShow = false}, 2000)},fail(err) {uni.showModal({content: '检测到您没打开获取信息功能权限,是否去设置打开?',confirmText: "确认",cancelText: '取消',success: (res) => {if (res.confirm) {uni.openSetting({success: (res) => {// console.log(res);// uni.showToast({// title: "请重新点击分享保存图片~",// icon: "none"// });}})} else {uni.showToast({title: "保存失败,请打开权限功能重试",icon: "none"});}}})}})}}, this);}}}
</script><style scoped lang="scss">.content {position: fixed;top: 0;left: 0;right: 0;bottom: 0;background: rgba(0, 0, 0, .4);display: flex;flex-direction: column;justify-content: center;align-items: center;z-index: 9999;}.save-btn {margin-top: 24rpx;padding: 15rpx 40rpx;border-radius: 50rpx;display: flex;flex-direction: column;justify-content: space-around;align-items: center;}text {font-size: 24rpx;}image {width: 90rpx;height: 90rpx;margin-bottom: 16rpx;}
</style>
最终效果图如下