当前位置: 首页 > 工具软件 > QRCanvas > 使用案例 >

Vue.js结合Canvas制作二维码和图片的合成(qrcanvas + html2canvas)

牟子真
2023-12-01

(这个有问题,最近会把整理后的更新上去!!!!!!)

最新最新!!!:https://blog.csdn.net/zuorishu/article/details/88632978

需求背景:

 分享图片,图片中含有自己分享链接生成的二维码!!

大体思路:

  • 第一步、根据自己的分享链接生成一张二维码;
  • 第二步、结合一张图片合成带分享二维码的大图;

开干:

首先来生成二维码,之前都是使用jQuery.qrcode这个插件进行二维码生成,使用vuejs后不想依赖jQuery,就重新找了一个

qrcanvas,使用方法上篇博客有提到,这里结合图片再来引用一下。

1.npm安装:npm install qrcanvas

2.页面引入:import { qrcanvas } from 'qrcanvas';

3.html:写一个带id(id自定义)的div

<template>
    <div class="container">
        <div class="box" ref="box">
            <div id="qrcode"></div>
        </div>
    </div>
</template>

4.js很简单

    created() {
        let that = this;
        that.$nextTick(function () {
           var canvas1 = qrcanvas({
                data: decodeURIComponent(that.$route.query.url), //分享链接(根据需求来)
                size:128 //二维码大小
            });
            document.getElementById("qrcode").innerHTML = '';
            document.getElementById('qrcode').appendChild(canvas1);
       })
    },

到这里二维码也就生成了,下面要实现二维码和图片进行合成,因为需求图片是固定一张,所以不用去处理图片动态改变的逻辑,图片直接就在本地引用了。首先要把图片放到页面上,二维码在图片上的具体位置根据需求自己css处理。html改造:

<template>
    <div class="container">
        <div class="box" ref="box">
            <!-- 图片 -->
            <img src="../assets/images/activity/txvip.jpeg" alt="分享背景图">
            <!-- 二维码 -->
            <div id="qrcode" class="qrcode"></div>
        </div>
    </div>
</template>

放完图片以后,接下来就是处理图片合成的问题。这里我用的是 html2canvas 这个插件,将html DOM元素或页面利用canvas画布生成图片。下面说一下用法:

1.npm安装

npm install html2canvas --save

2.页面引入

import html2canvas from 'html2canvas';

3.js很简单

 //that.$refs.box  生成图片的dom元素         
html2canvas(that.$refs.box).then(function(canvas) {
    console.log(canvas) //生成canvas画布
    console.log(canvas.toDataURL()) //将canvas转为base64图片
});

目前发现一个问题:针对微信内置浏览器是不支持base64格式长按的一些操作(因为以下是直接base64展示的);

解决办发:转成base64以后上传到后台存储到服务器,通过后台返回图片链接展示到页面上。。。

到这里图片就生成了,那么就是展示图片以并可以长按保存,没有做分享处理。接着再改造html

<template>
    <div class="container">
        <!-- 最后生成的图片展示 -->
        <div class="share-img">
            <img :src="imgUrl" alt="分享图片">
        </div>
        <!-- 生成图片的DOM -->
        <div class="box" ref="box">
            <img src="../assets/images/activity/txvip.jpeg" alt="分享背景图">
            <div id="qrcode" class="qrcode"></div>
        </div>
    </div>
</template>

生成新的图片以后页面上生成图片的DOM并没有隐藏掉,自己可以通过css或js处理。

看一下完整代码吧:

<!-- 分享图片生成 -->
<template>
    <div class="container">
        <div class="share-img">
            <img :src="imgUrl" alt="分享图">
        </div>
        <div class="creat-img" ref="box">
            <img src="../assets/images/activity/txvip.jpeg" alt="分享背景图">
            <div id="qrcode" class="qrcode"></div>
        </div>
    </div>
</template>

<script>
import { qrcanvas } from 'qrcanvas';
import html2canvas from 'html2canvas';
export default {
    data () {
        return {
            imgUrl:'',
        }
    },
    watch:{
        imgUrl(val,oldval){
            //监听到imgUrl有变化以后 说明新图片已经生成 隐藏DOM
            this.$refs.box.style.display = "none";
        }
    },
    created() {
        let that = this;
        that.$nextTick(function () {
           //生成二维码
           var canvas1 = qrcanvas({
                data: decodeURIComponent(that.$route.query.url),
                size:128
            });
            document.getElementById("qrcode").innerHTML = '';
            document.getElementById('qrcode').appendChild(canvas1);

            //合成分享图
            that.$indicator.open({
                text: '正在生成图片...',
                spinnerType: 'fading-circle'
            });
            html2canvas(that.$refs.box).then(function(canvas) {
                that.imgUrl =  URL.createObjectURL(that.base64ToBlob(canvas.toDataURL()))                
                setTimeout(()=>{
                    that.$indicator.close(); 
                    that.$toast({
                        message: '图片已生成,长按保存分享给你的好友吧',
                        position: 'middle',
                        duration: 3000
                    });                   
                },2000)
            });
       })
    },
    
    methods: {
        //base64转blob
        base64ToBlob(code) {
            let parts = code.split(';base64,');
            let contentType = parts[0].split(':')[1];
            let raw = window.atob(parts[1]);
            let rawLength = raw.length;

            let uInt8Array = new Uint8Array(rawLength);

            for (let i = 0; i < rawLength; ++i) {
            uInt8Array[i] = raw.charCodeAt(i);
            }
            return new Blob([uInt8Array], {type: contentType});
        },
    }
}

</script>
<style lang='scss' scoped>
.creat-img{
    img{
        z-index: 3;
    }
    .qrcode{
        position: absolute;
        bottom: .15rem;
        left: 50%;
        margin-left: -64px;
        z-index: 5;
    }
}

</style>

刚开始写,大体能用,有不足的地方请多指教!

 类似资料: