前端生成带有logo的二维码并保存

一、将生成的二维码与logo图标合并并保存二维码

需求:
1、前端自己生成带有logo的二维码并保存二维码
2、logo是图片

思路:
1、引用生成二维码的库(此处使用的是node-qrcodel,该库是目前我找到仍然在维护,且GitHub上星比较多的,但是生成的二维码不带logo,需要自己把logo加进去),插件链接
2、使用node-qrcode生成不带logo的二维码
3、将 logo 图片转换成 canvas(使用了 canvas 的 drawImage 方法:ctx.drawImage(logoImg, 4, 4, 32, 32);
4、将第3步生成的 logo canvas 与第2步生成的 二维码合并
5、保存二维码图片(使用了toDataURL

二、实现步骤

1、html代码

<div class="qrcode" v-show="_showCode">
  <img v-show="false" src="/media/img/logo.png" alt="" ref="logoImg">
    <div class="qrcodeCanvas">
      <canvas ref="qrcodeCanvas"></canvas>
    </div>
    <a href="javascript:;" class="button button-primary" @click="downloadCode">保存二维码</a>
  </div>
import QRCode from 'qrcode'; 	//引入生成二维码的库

在这里插入图片描述

说明:
1、logoImg是二维码中间的logo,这里预先加载进来,防止后面转换的时候获取不到图片。
2、logo 不能太大,不然二维码扫描不到内容,此处整个canvas画布是200200,logo是4040

2、logo图片转canas

imgToggleCanvas() {
      const canvas = document.createElement('canvas');
      const { logoImg } = this.$refs;
      const ctx = canvas.getContext('2d');
      ctx.fillStyle = '#FFFFFF';
      ctx.fillRect(0, 0, 40, 40);		//先画一个40*40的正方形,颜色#ffffff,此处因为logo图片四周没有留白
      ctx.drawImage(logoImg, 4, 4, 32, 32);		//将 32*32 的 logoImg 画到 canvas 上
      return canvas;
},

3、生成的 logo cavans与二维码 canvas 合并

mergeCanvas(generateCanvas) {		//生成的二维码 canvas	
      const { qrcodeCanvas } = this.$refs;
      const logoCavans = this.imgToggleCanvas();		//第2步里面的转换后的canvas
      const canvas = document.createElement('canvas');
      canvas.width = generateCanvas.width;
      canvas.height = generateCanvas.height;
      canvas.getContext('2d').drawImage(generateCanvas, 0, 0);	//将 generateCanvas 画到 canvas 上,坐标 0,0
      canvas.getContext('2d').drawImage(logoCavans, 80, 80);	//将 logoCavans 画到 canvas 上,坐标 80,80
      qrcodeCanvas.width = canvas.width;
      qrcodeCanvas.height = canvas.height;
      qrcodeCanvas.getContext('2d').drawImage(canvas, 0, 0);
},

4、生成二维码

// 生成二维码
 generateQrcode() {
    const options = {
      width: 200,
      height: 200,
    };
    QRCode.toCanvas(this.link, options)
      .then((el) => {
        this.showCode = true;		//showCode 决定是否显示二维码
        this.mergeCanvas(el);		//生成二维码后,合并二维码
      })
      .catch((err) => {
        this.showCode = false;
      });
  },

5、保存二维码

downloadCode(event) {
    const { qrcodeCanvas } = this.$refs;
    const url = qrcodeCanvas.toDataURL('image/png');
    //h5 的download属性在IE上,只从IE13开始兼容,所以需要 `window.navigator.msSaveOrOpenBlob` 里兼容IE10、11,IE9仍然无法兼容
	if (window.navigator.msSaveOrOpenBlob) {    //IE
	   const bstr = atob(url.split(',')[1])
       let n = bstr.length
        var u8arr = new Uint8Array(n)
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n)
        }
        const blob = new Blob([u8arr])
        window.navigator.msSaveOrOpenBlob(blob, '{% trans "Link QR code.png" %}')
    } else {		//非IE
       $(event.target).attr('href', url);
        $(event.target).attr('download', '{% trans "Link QR code.png" %}');
    }
   }

说明:因为后来考虑到 IE9及其他不兼容 download 属性的浏览器下载问题,将 qrcodeCanvas.toDataURL('image/png'); 生成的base64传给了后端,后端实现下载功能,前端及后端python代码如下:

var event= event||window.event;
var qrcodeCanvas=$('#qrcode_canvas')[0];
var url = qrcodeCanvas.toDataURL('image/png');
var downloadQRcode=$('#downloadQRcode');		//此处是一个表单,使用表单的 post 来提交 base64 数据
$('input.base64',downloadQRcode).val(url.split(',')[1]);		//提交的base64数据,此处仅提交 base 64 内容
$('input[type="submit"]',downloadQRcode).click();	//表单提交,另外在提交的时候,最好禁止表单提交的默认事件,即打开新的页面
def download_base64_img(request):
    base64_str =request.POST.get('base64data', '')
    from django.http import StreamingHttpResponse
    import base64
    imagedata = base64.b64decode(base64_str)
    response = StreamingHttpResponse(imagedata)
    response['content-type'] = "application/octet-stream"
    response['Content-Disposition'] = 'attachment;filename=QR_code.png'
    return response
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值