vuejs中html2canvas使用 背景图和二维码海报图片保存到一张图片上 生成一张海报并下载

不少的项目中都用到了二维码加背景图片生成海报的宣传图片,实现方法就是canvas绘制到一张上后进行下载。html2canvas的技巧在这里不在讲解。

二维码和背景图片进行定位。

在传统场合,这类功能往往依赖后台合成图片,或依赖端上实现,但web侧本身也有独立的解决方案。 Web中具有图片生成功能的是canvas标签,我们可以使用canvas中的toDataUrl() API,得到当前画布内容的base64 data URI,即图片数据。

toDataUrl() api描述

所以,最直接的思路是,把个性化内容绘制在canvas上,使用api转成图片。 但这样还是太繁琐,要和大量的绘制api打交道,不直观,不便于复用。web侧最直观的就是dom内容,如果能把dom内容快速转换成canvas,由canvas再转成图片,就可以快速实现上述功能。 万幸的是,我们有一个强大的工具——html2canvas。

html2canvas是一套由个人开发的开源工具,用于把html标签绘制的dom内容转为canvas。

通过一个异步的过程,将html图片转换为canvas,再调用canvas的api,得到dataURL,最后,把data URL赋给img标签的src属性,从而生成一张完整的图片。

我们关注调用参数

canvas

转换用的canvas容器,注意,该容器可以提前写入dom,也可以像上述代码所示,动态创建。两种调用方法并无区别,如果动态创建,不挂进dom树,则该容器全程是不可见的,所以对于单张一次性的图片生成,更推荐这种方式。

<div class="big_codebox ">
<h4 class=" font-20 font-bold padd01">二维码海报</h4>
<div class="big_code bot_top">
  <div class="code">
    <template>
      <div>
        <!-- ref="box" 是 需要保存图片的div盒子 -->
        <div ref="box" id="shareImg">
          <img :src='require("../../assets/images/user/tgbg.png")' alt="">// 背景图
          <div class="imgs2">
            <img :src='qrmcodeSrc' alt="" class="codeimg"> //二维码
            <p class="codeimgtxt">邀请码:{
   
   {tjCode}}</p>  //二维码上的文字
          </div>
        </div>
        <!--生成的合成图片-->
        <!-- <img :src="imgUrl" alt=""> -->
        <!-- <img :src="'data:image/jpeg;base64,' + downloadUrl"/> -->
      </div>
    </template>
    <el-button type="primary" class="m20" @click="saveImage('box','推广二维码')">点击按钮保存二维码海报,去社交媒体推广</el-button>
  </div>
</div>
</div>

代码中的 // 注释需要删除,在这里是为了方便大家理解。这里需要用到 html2canvas 工具,

import VueQr from "vue-qr";
import html2canvas from 'html2canvas';
data() {
    TGurl:'',
    myMlink:'',
    tjCode:'',
    imgUrl:'',
    shopPic:'',
    rowData:'',
    downloadUrl:'',
    divText:'box',
    imgText:'好友推广二维码'
}

思路及部分代码如下:

1、将图片样式布局好,给需要保存的div 添加 ref="" 属性

2、看代码吧

this.test();//获取database64 url,在获取到参数后,直接使用这个方法

test(dataUrl,id){
        // console.log(dataUrl, id);
        this.qrmcodeSrc=dataUrl;
        // console.log(this.qrmcodeSrc);
        this.draw()
    },
draw(){
      if(this.qrmcodeSrc) return
        var that = this;
        if(this.qrmcodeSrc) return
        html2canvas(that.$refs.box).then(function(canvas) {
          that.imgUrl = canvas.toDataURL()//将canvas转为base64图片(eg. data:image/png;base64,ijskjlkj)
        });
    },
//图片转换格式的方法 直接使用就好 不需要知道为什么
dataURLToBlob(dataurl) {
  let arr = dataurl.split(',');
  let mime = arr[0].match(/:(.*?);/)[1];
  let bstr = atob(arr[1]);
  let n = bstr.length;
  let u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], { type: mime });
},
/*保存图片的方法(即按钮点击触发的方法)
第一个参数为需要保存的div的id名
第二个参数为保存图片的名称 */
saveImage(divText, imgText) {
  let canvasID = this.$refs[divText];
  let that = this;
  let a = document.createElement('a');
  html2canvas(canvasID).then(canvas => {
    let dom = document.body.appendChild(canvas);
    dom.style.display = 'none';
    a.style.display = 'none';
    document.body.removeChild(dom);
    let blob = that.dataURLToBlob(dom.toDataURL('image/png'));
    a.setAttribute('href', URL.createObjectURL(blob));
    //这块是保存图片操作 可以设置保存的图片的信息
    a.setAttribute('download', imgText+this.tjCode + '.png');//二维码图片名称
    document.body.appendChild(a);
    a.click();
    URL.revokeObjectURL(blob);
    document.body.removeChild(a);
  });
},

分享一个案例代码


<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
	<!-- <meta http-equiv="Content-Security-Policy" content="script-src 'self' *.url.cn *.idqqimg.com *.qq.com *.gtimg.cn 'unsafe-inline' 'unsafe-eval';">      -->
	<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
	<meta name="apple-mobile-web-app-capable" content="yes" />
	<meta name="apple-mobile-web-app-status-bar-style" content="black" />
	<meta name="Copyright" content="Tencent" />
	<meta name="format-detection" content="telephone=no" />
	<title></title>
    <script></script>
    <style>
		/*commonArea,手Q中H5页面通用css基础样式区域*/
    	html,body, div, p, ol, ul, li, table, tbody, tr, td,
        form, h1, h2, h3, h4, h5, dl, dt, dd, img, iframe, header, nav,
        section, article, footer, figure, figcaption, menu, a, p,button {padding: 0;margin: 0; -webkit-user-select: none; -moz-user-select: none; -webkit-text-size-adjust: none;-webkit-touch-callout: none;}
        textarea,input{padding: 0;margin: 0;}
        html ,body{ width: 100%; height: 100%;}
        body { font-size: 62.5%; font: 16px "Helvetica Neue", Helvetica, STHeiTi, "\5FAE\8F6F\96C5\9ED1", sans-serif; min-width: 320px; margin: 0 auto;background:#ece0c1}
        em{ font-style: normal;}
        a, span { text-decoration: none;display: inline-block;}
        a:link, a:visited{text-decoration:none;}
        a,button{outline: none; -webkit-tap-highlight-color:rgba(0,0,0,0);}
        button{border:none; background: transparent;}
		li {list-style: none;}
        body{
            text-align: center;
        }
        #content{
            position: relative;
            margin:auto;
			margin-top:50px;
            width:588px;
            height:849px;
            box-sizing: border-box;
            overflow:hidden;
        }
        .letter-content{
            background-position: 0 0;
            background-repeat: no-repeat;
            background-size: 100% 100%;
            position: absolute;
            top:0;
            left:0;
            width:588px;
            height:849px;
        }
        .copyImage{
            width: 100%;
            position: absolute;
            top:0;
            left:0;
            z-index: 10002;
            width:588px;
            height:849px;
            opacity:0;
        }
        .letter-title{
            position: absolute;
            top: 420px;
            left: 0;
            color: #d9feec;
            text-shadow: 0 0 0.4em #348132, 0 0 0.4em #348132;
            text-align: center;
            width:100%;
            font-size:48px;
            z-index: 10001;
        }
        .letter-bg{
            width: 588px;
            height: 849px;
            position: absolute;
            top: 0;
            left: 0;
            z-index:10000;
            background-image: url("./bg.jpg");
            background-size: 100% 100%;
            /* box-shadow: #348132 10px 10px 10px; */
        }
        button{
            font-size:24px;
            border:1px solid gray;
            padding:10px 0;
            margin:10px;
            width:200px;
        }
        button:active{
            background:#fafafa;
        }
    </style>
    </head>
    <body ontouchstart="">
        <div id="content">
            <img src="" class="copyImage">
            <div class="letter-content" id="letter">
                <p class="letter-title">1970:0:0</p>
                <div class="letter-bg">
                    <!-- <img id="letter-bg-img" src="https://sqimg.qq.com/qq_product_operations/qim/film/share/pink_letter.png"> -->
                </div>
                <div class="ecode"></div>
            </div>
        </div>
        <button id="change-style">圆角透明</button>
        <button id="save-local">保存到本地</button>
        <a id="dl-hidden" style="display:none;"></a>
    </body>
    <script src="./zepto.js"></script>
    <script src="./html2canvas.min.js"></script>
    <script>
        window.onload = function(){
        var IMAGE_URL;
        function takeScreenshot(){
            var shareContent = document.getElementById('letter');//需要截图的包裹的(原生的)DOM 对象
            var width = shareContent.offsetWidth; //获取dom 宽度
            var height = shareContent.offsetHeight; //获取dom 高度
            var canvas = document.createElement("canvas"); //创建一个canvas节点

            var scale = 2; //定义任意放大倍数 支持小数
            canvas.width = width * scale; //定义canvas 宽度 * 缩放
            canvas.height = height * scale; //定义canvas高度 *缩放
            canvas.getContext("2d").scale(scale,scale); //获取context,设置scale

            // var rect = shareContent.getBoundingClientRect();//获取元素相对于视察的偏移量
            // canvas.getContext("2d").translate(-rect.left,-rect.top);//设置context位置,值为相对于视窗的偏移量负值,让图片复位
            var opts = {
                scale:scale, // 添加的scale 参数
                canvas:canvas, //自定义 canvas
                logging: true, //日志开关
                width:width, //dom 原始宽度
                height:height, //dom 原始高度
                backgroundColor: 'transparent',
            };
            html2canvas(shareContent, opts).then(function (canvas) {
                IMAGE_URL = canvas.toDataURL("image/png");
                $('.copyImage').attr('src',IMAGE_URL);
            })
        }

        function dataURLtoBlob(dataurl) {
            var arr = dataurl.split(','),
                mime = arr[0].match(/:(.*?);/)[1],
                bstr = atob(arr[1]),
                n = bstr.length,
                u8arr = new Uint8Array(n)
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n)
            }
            return new Blob([u8arr], { type: mime })
        }

        function downloadBase64(dataUrl, filename) {
            var imageFile, href
            // const downloadLink = document.createElement('a')
            var downloadLink = document.getElementById('dl-hidden')
            try {
                var blob = dataURLtoBlob(dataUrl)
                    var href = window.URL.createObjectURL(blob)
                    downloadLink.download = filename
                    downloadLink.href = href
                    downloadLink.click()
            } catch (err) {
            } finally {
                if (href) {
                    window.URL.revokeObjectURL(href)
                }
                // downloadLink.remove()
            }
        }

				$(".letter-title").text(new Date().toLocaleString());
				takeScreenshot();
				var curStyle=0;
				$("#change-style").click(function(e){
						takeScreenshot();
						if(curStyle==0){
								$(".letter-content").attr("style","opacity:0.8;");
								$(".letter-bg").attr("style","border-radius:50px;");
								$("#change-style").text("普通");
								curStyle=1;
						}else{
								$(".letter-content").attr("style","opacity:1;");
								$(".letter-bg").attr("style","border-radius:0;");
								$("#change-style").text("圆角透明");
								curStyle=0;
						}
				})
				$("#save-local").click(function(e){
						downloadBase64(IMAGE_URL, '合成图.png')
				})
    }
</script>
</html>

不懂的朋友,可以关注二维码进行讨论哦!

好了,如果有不懂的问题,可以关注我的个人微信公众号和我交流

同时还可以领取到前端学习资料!欢迎大家关注。和我一起讨论学习交流H5前端开发。

猜你喜欢

转载自blog.csdn.net/u012118993/article/details/99092277