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

by admin on 2020年1月5日

在项目中经常会遇到需要将不同的二维码放到一张通用图片上,提供用户下载,简单来说,就是利用canvas将同等比例的二维码在图片上叠加,生成海报

本文实例为大家分享了canvas二维码和图片合成海报的具体代码,供大家参考,具体内容如下

使用JavaScript将图片拷贝进画布

前端需要做分享功能。生成二维码后
在指定的图片上添加二维码和邀请码生成新的图片。

  1. 设置相应比例

思路:在微信中登录,后台传来的是一个链接、一个名字、一张图片。把图片当做背景,画满整个画布。之后需要把链接转为二维码,使用jq.qrcode转化,转化完成后是一个canvas,把这个canvas再转成一张图片,画到大的画布上。把名字画到画布上。把整张画布转为图片。

要想将图片放入画布里,我们使用canvas元素的drawImage方法:

1.使用 qr-code生成二维码

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

一、定义画布和合成海报的img

// Converts image to canvas; returns new canvas element
function convertImageToCanvas(image) {
    var canvas = document.createElement("canvas");
    canvas.width = image.width;
    canvas.height = image.height;
    canvas.getContext("2d").drawImage(image, 0, 0);       
return canvas;
}
/*** 根据url 地址生成 二维码*/async createQr(url, name) { let qr_png = qr.image(url, { type: ‘png‘, size: 8, margin: 2 }); let imgName = `${this.app.config.share_path}/${name}.png`; let qr_pipe = qr_png.pipe(fs.createWriteStream(imgName)); return await new Promise((resolve, reject) = { qr_pipe.on(‘error‘, function(err) { console.log(err); resolve(null); }); qr_pipe.on(‘finish‘, function() { resolve(imgName.substring(3, imgName.length)); }); }).then(data = data);}
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: '',// 合成图片 } }};
#canbox { width: 100%; height: 100%; position: fixed; top: 0; bottom: 0; left: 0;}.canimg { width: 100%; height: 100%; position: fixed; top: 0; bottom: 0; left: 0;}

这里的0, 0参数画布上的坐标点,图片将会拷贝到这个地方。

2.使用text-to-svg 生成邀请码图片,字符转图片

  1. 获取屏幕宽度

二、用jquery.qrcode把网址变成二维码

 

const textToSVG = TextToSVG.loadSync(); const svg = textToSVG.getSVG(id + ‘‘, { x: 0, y: 0, width: 80, height: 32, fontSize: 22, anchor: ‘left top‘, attributes: { fill: ‘white‘, // 字体颜色 stroke: ‘black‘, },});

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

后台传过来的是网址,需要转为二维码,二维码也是canvas,需要把二维码转为图片

用JavaScript将画布保存成图片格式

3.使用gm工具合成图片

computed: { screenWidth(){ let w = document.body.clientWidt || document.documentElement.clientWidth || 375; return w  480 ? 480 : w ; }};
$.qrcode({ width: 72, //宽度 height: 72, //高度 text: res.data.poster_qrcode, //任意内容 });

如果你的画布上的作品已经完成,你可以用下面简单的方法将canvas数据转换成图片格式:

svg2png(svg).then(d = { console.log(‘@@@@@@@@‘); const n = `${this.app.config.share_path}/${name}_number.png`; fs.writeFile(`${n}`, d, err = { gm().in(‘-page‘, ‘0,0‘)// -page是设置图片位置,所有的图片以左上为原点,向右、向下为正 .in(sourceImg)// 底图,到这里第一张图就设置完了,要先设置参数,再设置图片 .in(‘-resize‘, ‘250x250‘)// 设置微信二维码图片的大小 .in(‘-page‘, ‘+110+210‘)// 设置微信二维码图片的位置 .in(waterImg)// 二维码图 .in(‘-page‘, ‘+210+532‘)// logo图位置 .in(n)// logo图 .mosaic()// 图片合成 .write(lastput, function(err) { // 图片写入 if (err) { console.log(err); reject(new Error(‘error!!!!!!!!!!!!!!!!‘)); } else { console.log(‘ok‘); resolve(lastput.substring(3, lastput.length)); } }); });});
  1. 组合图片

    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)}

  2. 下载

三、把图片画到画布上,需要占满全屏

// Converts canvas to an image
function convertCanvasToImage(canvas) {
    var image = new Image();
    image.src = canvas.toDataURL("image/png");
    return image;
}

点击下载合成图片

//画海报var width = document.getElementById.offsetWidth; //宽度 var height = document.getElementById.offsetHeight; // 高度var c = document.getElementById;c.width = widthc.height = heightvar ctx = c.getContext;//首先画上背景图var img = new Image();img.src = this.list.poster;img.setAttribute("crossOrigin", 'Anonymous')var x_bot = height - 44 //画上名字ctx.font = "19px Georgia";

//画上二维码function convertCanvasToImage { var image = new Image(); image.src = canvas.toDataURL; return image;}var mycans = $[1];//二维码所在的canvasvar codeimg = convertCanvasToImagevar xw = width - 72 - 29var xh = height - 6 - 72

img.onload = function() { //必须等待图片加载完成 ctx.drawImage(img, 0, 0, width, height); //绘制图像进行拉伸 ctx.fillText; ctx.drawImage(codeimg, xw, xh, 72, 72); //绘制完成,转为图片 setTimeout { //在ios上无法在画完之后取到整个画布内容,加了个settimeout var bigcan = $[0]; let images = new Image(); images.src = bigcan.toDataURL; alert(bigcan.toDataURL images.setAttribute("crossOrigin", 'Anonymous') $.attr('src', bigcan.toDataURL}

这段代码就能神奇的将canvas转变成PNG格式!

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:不适用于微信浏览器,只能提示用户长按保存。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图