在Vue中用canvas实现二维码和图片合成海报的方法


Posted in Javascript onJune 10, 2019

在项目中经常会遇到需要将不同的二维码放到一张通用图片上,提供用户下载

简单来说,就是利用canvas将同等比例的二维码在图片上叠加,生成海报

1. 设置相应比例

一般来说海报背景都是固定的,可以直接放在public文件夹,二维码可根据后台返回数据,也可用canvas生成,在此不多赘述

import posterBgImg from '../public/images/poster_bg.png';// 海报底图
import qrcodeImg from '../public/images/qrcode.png';// 二维码
export default{
  name: 'qrcode-in-poster',
  data(){
    return {
      posterBgImg,
      qrcodeImg,
      posterSize: 930/650,// 海报高宽比例
      qrCodeSize: {// 二维码与海报对应比例 =》 用于设置二维码在海报中的位置
        width: 270/650,
        height: 270/930,
        left: 190/650,
        top: 448/650
      },
      poster: '',// 合成图片
    }
  }
};

2. 获取屏幕宽度

限定移动端最大宽度为 480px

computed: {
  screenWidth(){
    let w = document.body.clientWidt || document.documentElement.clientWidth || 375;
    return w > 480 ? 480 : w ;
  }
};

3. 组合图片

methods: {
  combinedPoster(_url){
    let that = this,
      qrcode = this.qrcodeImg; // 二维码地址
  
    console.log("open draw: ", _url, qrcode)
    let base64 = '',
      canvas = document.createElement('canvas'),
      ctx = canvas.getContext("2d"),
      _w = this.screenWidth * 2, // 图片宽度: 由于手机屏幕时retina屏,都会多倍渲染,在此只设置2倍,如果直接设置等于手机屏幕,会导致生成的图片分辨率不够而模糊
      _h = this.posterSize * _w, // 图片高度
      _qr_w = this.qrCodeSize.width * _w, // 二维码宽 = 比例 * 宽度
      _qr_h = this.qrCodeSize.height * _h, // 二维码高 = 比例 * 高度
      _qr_t = this.qrCodeSize.top * _w, // 二维码顶部距离 = 比例 * 宽度
      _qr_l = this.qrCodeSize.left * _w; // 二维码左侧距离 = 比例 * 宽度
    // 设置canvas宽高  
    canvas.width = _w; 
    canvas.height = _h;
    ctx.rect(0, 0, _w, _h);
    ctx.fillStyle = '#fff'; // 填充颜色
    ctx.fill();
    // 迭代生成: 第一层(底图)+ 第二层(二维码)
    // file:文件,size:[顶部距离,左侧距离,宽度,高度]
    let _list = [ 
      {
        file: _url,
        size: [0, 0, _w, _h]
      }, {
        file: qrcode,
        size: [_qr_l, _qr_t, _qr_w, _qr_h]
      }
    ];
    // 开始绘画
    let drawing = (_index) => {
      // 判断当前索引 =》 是否已绘制完毕
      if (_index < _list.length) {
        // 等图片预加载后画图
        let img = new Image(),
          timeStamp = new Date().getTime();
        // 防止跨域
        img.setAttribute('crossOrigin', 'anonymous')
        // 链接加上时间戳
        img.src = _list[_index].file + '?' + timeStamp
        img.onload = function() {
          // 画图
          ctx.drawImage(img, ..._list[_index].size)
          // 递归_list
          drawing(_index + 1)
        }
      } else {
        // 生成图片
        base64 = canvas.toDataURL("image/png")
        if (base64) {
          // 赋值相应海报上
          this.$set(that, 'poster', base64)
        }
      }
    }
    drawing(0)
  }
};
mounted(){
  // 需要合成海报的图片
  this.draw(this.posterBgImg)
}

4. 下载

点击下载合成图片

methods: {
  handleDownload(){
    if(this.poster){
      let a = document.createElement("a");
      a.setAttribute("download", "海报下载-"+(new Date().getTime()));
      a.href = this.poster
      a.click()
    }else{
      console.log("海报不存在,请重新生成!")
    }
  }
}

tips:不适用于微信浏览器,只能提示用户长按保存。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
wordpress之js库集合研究介绍
Aug 17 Javascript
jquery $.ajax入门应用二
Nov 19 Javascript
js限制textarea每行输入字符串长度的代码
Oct 31 Javascript
JS在textarea光标处插入文本的小例子
Mar 22 Javascript
js简单实现让文本框内容逐个字的显示出来
Oct 22 Javascript
Node.js事件驱动
Jun 18 Javascript
Vuejs第一篇之入门教程详解(单向绑定、双向绑定、列表渲染、响应函数)
Sep 09 Javascript
JavaScript字符串检索字符的方法
Jun 23 Javascript
AngularJS页面带参跳转及参数解析操作示例
Jun 28 Javascript
Angular中的$watch方法详解
Sep 18 Javascript
vue移动端下拉刷新和上拉加载的实现代码
Sep 08 Javascript
一些可能会用到的Node.js面试题
Jun 15 Javascript
vue中使用 pako.js 解密 gzip加密字符串的方法
Jun 10 #Javascript
移动端 Vue+Vant 的Uploader 实现上传、压缩、旋转图片功能
Jun 10 #Javascript
利用百度echarts实现图表功能简单入门示例【附源码下载】
Jun 10 #Javascript
jquery操作checkbox的常用方法总结【附测试源码下载】
Jun 10 #jQuery
利用Electron简单撸一个Markdown编辑器的方法
Jun 10 #Javascript
js实现类似iphone的网页滑屏解锁功能示例【附源码下载】
Jun 10 #Javascript
基于jquery实现的tab选项卡功能示例【附源码下载】
Jun 10 #jQuery
You might like
php实现多张图片上传加水印技巧
2013/04/18 PHP
PHP foreach遍历多维数组实现方式
2016/11/16 PHP
PHP开发APP端微信支付功能
2017/02/17 PHP
PHP实现的只保留字符串首尾字符功能示例【隐藏部分字符串】
2019/03/11 PHP
thinkPHP+mysql+ajax实现的仿百度一下即时搜索效果详解
2019/07/15 PHP
jQuery lazyload 的重复加载错误以及修复方法
2010/11/19 Javascript
使用jquery mobile做幻灯播放效果实现步骤
2013/01/04 Javascript
jquery复选框全选/取消示例
2013/12/30 Javascript
jQuery中多个元素的Hover事件解决方案
2014/06/12 Javascript
JQuery右键菜单插件ContextMenu使用指南
2014/12/19 Javascript
JS实现选择TextArea内文本的方法
2015/08/03 Javascript
jQuery网页右侧广告跟随滚动代码分享
2020/04/20 Javascript
浅析jQuery移动开发中内联按钮和分组按钮的编写
2015/12/04 Javascript
jquery实现下拉框多选方法介绍
2017/01/03 Javascript
探索Vue高阶组件的使用
2018/01/08 Javascript
vue 组件高级用法实例详解
2018/04/11 Javascript
JS基于封装函数实现的表格分页完整示例
2018/06/26 Javascript
微信小程序提取公用函数到util.js及使用方法示例
2019/01/10 Javascript
详解一次Vue低版本安卓白屏问题的解决过程
2019/05/30 Javascript
Vue实现日历小插件
2019/06/26 Javascript
详解js中的几种常用设计模式
2020/07/16 Javascript
js实现滑动滑块验证登录
2020/07/24 Javascript
基于vue的video播放器的实现示例
2021/02/19 Vue.js
vue项目配置 webpack-obfuscator 进行代码加密混淆的实现
2021/02/26 Vue.js
python读取json文件并将数据插入到mongodb的方法
2015/03/23 Python
python插入数据到列表的方法
2015/04/30 Python
Django进阶之CSRF的解决
2018/08/01 Python
python Pillow图像处理方法汇总
2019/10/16 Python
python连接mongodb集群方法详解
2020/02/13 Python
matplotlib jupyter notebook 图像可视化 plt show操作
2020/04/24 Python
Python 实现敏感目录扫描的示例代码
2020/05/21 Python
Python正则re模块使用步骤及原理解析
2020/08/18 Python
英国高级百货公司:Harvey Nichols
2017/01/29 全球购物
水务局局长岗位职责
2013/11/28 职场文书
后勤人员岗位职责
2013/12/17 职场文书
六五普法先进个人主要事迹材料
2015/11/03 职场文书