qrcodejs2生成二维码,通过canvas绘制带边框+中间logo的二维码图片,下载二维码

news2024/11/26 19:57:14

文章目录

    • 一、通过qrcodejs2生成一个二维码
    • 二、点击【下载配置服务器二维码】来下载二维码
      • 1、通过canvas去绘制 边框+二维码+logo
        • (1)为canvas增加绘制圆角矩形的方法(canvas本身不提供)
        • (2)通过canvas绘制 圆角边框 + 二维码 + logo
      • 2、通过a.download 去下载图片

一、通过qrcodejs2生成一个二维码

粗略代码,部分代码省略。
在 view.vue 文件中,HTML部分

<template>
	<div>
		<div class="step">
			<p class="til">步骤二:对App配置服务器</p>
			<div class="step-con">
				<div class="img-box">
					<!-- 存放生成的二维码的div -->
					<div class="qrcode-config" ref="qrcode-config"></div>
					<!-- 中间的logo,通过position:absolute;定位到中间 -->
					<img class="qrcode-logo" width="27" src="@/assets/img/logo.png" alt="配置服务器">
				</div>
				<div class="desc">
					<a class="link" href="javascript:void(0)" @click.prevent="downloadImg">下载配置服务器二维码</a>
				</div>
			</div>
		</div>
		<div class="step">
			<p class="til">步骤三:登录企业帐号,开始使用</p>
		</div>
	</div>
</template>

view.vue 文件,javascript 部分

<script>
import QRcode from 'qrcodejs2';
export default {
	name: "viewPage",
	data() {
		return {}
	},
	methods:{
		// 生成二维码
		createQrcode() {
			new QRcode(this.$refs['qrcode-config'],{
				text: "wataru is the best", // 扫二维码后获得的信息
				width: 90, // 图片宽90px,左右padding各4px,边框各1px, 100-8px-2px
				height: 90, // 图片高90px,上下padding各4px,边框各1px, 100-8px-2px
			})
		}
	},
	mounted() {
		this.$nextTick(() => {
			this.createQrcode();
		});
	}
}
</script>

view.vue 文件,scss 样式部分,设计要求二维码要有圆角边框

<style lang="scss">
/* 二维码图片容器,包括二维码 + logo + 边框 */
.img-box {
	padding-bottom: 8px;
	width: 100px;
	height: 100px;
	box-sizing: border-box;
	position: relative;
}
/* qrcodejs2 生成的二维码的容器,纯二维码*/
.qrcode-config {
	border: 1px solid #e5e5e6;
	padding: 4px;
	border-radius: 4px;
	width: 100px;
	height: 100px;
	box-sizing: border-box;
	img {
		box-sizing: border-box;
	}
}
/*二维码中间的logo*/
.qrcode-logo {
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
	width: 27px;
}
</style>

qrcodejs2生成的二维码样式:
在这里插入图片描述

通过加圆角边框 + logo 定位展示的二维码样式 :

在这里插入图片描述

二、点击【下载配置服务器二维码】来下载二维码

1、通过canvas去绘制 边框+二维码+logo
2、通过a.download 去下载图片

1、通过canvas去绘制 边框+二维码+logo

(1)为canvas增加绘制圆角矩形的方法(canvas本身不提供)

方法参考来源: 详述Canvas(五)/绘制圆角矩形 - 作者:泥猴桃
上面文章详细讲解了坐标的计算,有兴趣的可以前去查看。
CanvasRenderingContext2D.prototype.roundRect = function(){} 这一步可以放到 this.createQrcodemounted 中,在绘制canvas之前先扩展绘制圆角矩形的方法。
如果要下载的二维码不需要圆角边框 ,可以省略这一步,但是在drawQrcode方法中,context.roundRect(0, 0, 100, 100, 4).stroke();context.fill()等要做出相应修改。

相关canvas 属性和方法 可查看以下两个链接:
1、Canvas fillRect() 方法 - W3C School
2、HTML DOM Canvas 对象 - W3C School

// 增加绘制圆角矩形的方法
CanvasRenderingContext2D.prototype.roundRect = function(x, y, w, h, r) {
	// x: 水平坐标轴位置,y:垂直坐标轴位置,w: 圆角矩形的宽度,h:圆角矩形的高度,r:圆角矩形的圆角半径
	if(w < 2 * r) { r = w / 2 };
	if(h < 2 * r) { r = h / 2 };
	// 起始一条路径,或重置当前路径。告诉浏览器可以开始绘制
	this.beginPath();
	// 光标移动到 x+r,y 的定位,移动到画布中的指定点,不创建线条。
	this.moveTo(x+r, y);
	// 开始画线, arcTo 创建两切线之间的弧/曲线。
	this.arcTo(x+w, y, x+w, y+h,r);
	this.arcTo(x+w, y+h, x,y+h,r);
	this.arcTo(x, y+h, x,y,r);
	this.arcTo(x, y, x+w,y,r);
	// 创建从当前点回到起始点的路径。
	this.closePath();
	// 返回 this ,可使用链式语法。
	return this;
};

(2)通过canvas绘制 圆角边框 + 二维码 + logo

了解 globalCompositeOperation 属性可以前往:HTML canvas globalCompositeOperation 属性 | 菜鸟教程

// 绘制二维码,绘制边框+生成的二维码+logo
drawQrcode(callback) {
	const image = new Image();
	const logoImage = new Image();
	// 解决跨域问题
	image.setAttribute('crossOrigin', 'anonymous');
	logoImage.setAttribute('crossOrigin', 'anonymous');
	
	// 图片加载完成后,通过canvas处理
	const canvas = document.createElement('canvas');
	const context = canvas.getContext('2d');
	
	// qrcodejs2 生成的二维码加载完成后,开始 canvas 绘制
	image.onload = function() {
		// 通过canvas绘制,canvas的宽高设置为二维码图片宽高+10px,宽/高多的10px = 左/上边框宽度1px + 左/上间距4px + 右/下间距4px + 右/下边框宽度1px
		canvas.width = image.width + 10;
		canvas.height = image.height + 10;
		// canvas 绘制线条的宽度设置为1px,线条的颜色设置为 #e5e5e6 
		context.lineWidth = 1;
		context.strokeStyle = "#e5e5e6";
		/*
			globalCompositeOperation 属性设置或返回如何将一个源(新的)图像绘制到目标(已有的)的图像上。
			源图像 = 您打算放置到画布上的绘图。
			目标图像 = 您已经放置在画布上的绘图。
			source-over:默认。在目标图像上显示源图像。
		*/ 
		context.globalCompositeOperation = "source-over";
		context.roundRect(0, 0, 100, 100, 4).stroke(); // 绘制圆角矩形的范围
		// 圆角矩形的范围填充白色
	    context.fillStyle ="rgba(255,255,255,1)";
	    context.fill();
		// padding:4px + border:1px,4 + 1 = 5
		context.drawImage(image,5, 5, image.width, image.height); // 目标图像
		context.roundRect(0, 0, 100, 100, 4).stroke();// 源图像,重新在canvas上绘制圆角边框的线,drawImage的时候被覆盖掉了

		// 中间的logo加载完成后,绘制logo
		logoImage.onload = function() {
			// logo的宽高设置为27px,如果是想根据logo本身的宽高作为长度,可以把27换为logoImage.width,logoImage.height
			let logoX = 4 + (image.width - 27) / 2;
			let logoY = 4 + (image.height - 27) / 2;
			// 绘制logo图像,context.drawImage(logoImage,logoX, logoY, logoImage.width, logoImage.height);
			context.drawImage(logoImage,logoX, logoY, 27, 27);
			// 将绘制的图像转为data:image的格式
			let url = canvas.toDataURL('image/png');
			// 将url传到回调函数中
			callback && callback(url);
		}
		// 获取logo的src,赋值给logoImage,触发logoImage的onload方法
		var qrimglogo = document.querySelector('.qrcode-logo');
		logoImage.src = qrimglogo.src;
	}
	// 获取二维码qrimg的src,赋值给image,触发image的onload方法
	let qrimg = this.$refs['qrcode-config'].querySelector('img');
	image.src = qrimg.src;
}

2、通过a.download 去下载图片

// 下载二维码图片
downloadImg(){
	// 先用canvas绘制二维码图片
	this.drawQrcode((url) => {
		// 利用 a 标签的 download 属性去下载图片
		let a = document.createElement('a');
		// 下载图片的名称设置为“配置服务器二维码”
		a.download = "配置服务器二维码";
		a.href = url;
		// 创建一个点击事件
		const clickEvent = new MouseEvent('click');
		// 触发 a 标签的点击事件
		a.dispatchEvent(clickEvent);
	});
}

点击下载:
在这里插入图片描述
下载后的二维码图片:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/627335.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

饮酒过多和腌制食品是导致中风的最大导火索

中风是一种常见的疾病&#xff0c;它的发生和饮食习惯有很大关系。近年来&#xff0c;我国中风病患人数和病发率都呈现出了不同程度的上升趋势&#xff0c;这给我们的健康带来了很大的威胁。下面我们可以通过数据可视化大屏来了解一下饮食健康与预防中风有哪些影响&#xff0c;…

ESP32-S3 边缘人工智能|使用加速度计数据和 ESP-DL 识别人体活动

边缘计算是一种分布式计算范例&#xff0c;指在更靠近设备的地方进行数据存储和计算。边缘人工智能&#xff08;边缘 AI&#xff09;是边缘计算中一项振奋人心的成果&#xff0c;可以令传统技术更高效地运行&#xff0c;在降低功耗的同时又有更好的性能。训练好的神经网络可以在…

通信算法之167: (低空无人机)机载视频通信传输系统基带算法设计

一.物理层基带仿真 通信系统的链路级仿真主要可以分成5个部分。 1.系统参数 2.发送机算法 3.信道模型 4.接收机算法 5.统计性能 其中主要组成部分很明显是中间三部分&#xff0c;即发送&#xff0c;信道&#xff0c;接收。但系统参数和统计性能这两部分的适当设计会大大…

linux基础命令系列之10 分钟掌握 ln 命令:创建链接,软链接,硬链接,递归链接,打印详细输出

文章目录 前言一. ln命令介绍二. 语法格式及常用选项三. 参考案例3.1 ln命令创建硬链接3.1.1 创建硬链接3.1.2 源文件被删除&#xff0c;不影响链接文件的正常使用3.1.3 硬链接不能跨分区创建 3.2 为什么目录刚刚创建的时候&#xff0c;链接数为23.3 ln -s 软链接的创建3.3.1 l…

【漏洞修复】node-exporter被检测出来pprof调试信息泄露漏洞

node-exporter被检测出来pprof调试信息泄露漏洞 说在前面解决方法结语 说在前面 惯例开篇吐槽&#xff0c;有些二五仔习惯搞点自研的安全扫描工具&#xff0c;然后加点DIY元素&#xff0c;他也不管扫的准不准&#xff0c;就要给你报个高中危的漏洞&#xff0c;然后就要去修复&…

C++元模板技术与traits解析:根据类型的特性来调整代码的行为,解决没有重载运算符的情况

C元模板技术与traits解析 第一章、C元模板技术简介 (C Meta-template Introduction)1.1 元模板的定义与概念 (Definition and Concepts)1.2 元模板技术的发展历程 (Evolution of Meta-templates)1.3 元模板应用场景举例 (Examples of Meta-template Applications) 第二章、 tra…

[数据结构初阶]顺序表

目录 静态顺序表 动态顺序表 初始化 销毁 尾插 ​编辑 尾删 头插 头删 Insert erase find查找 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构&#xff0c;一般情况下采用数组存储。在数组上完成数据的增删查改。 静态顺序表 定义结构体&#xff1…

Talk | 北卡罗来纳州立大学唐圣坤浙江大学张磊: 数据为中心的高效视觉语言学习—动态退出与数据蒸馏

本期为TechBeat人工智能社区第504期线上Talk&#xff01; 北京时间6月8日(周四)20:00&#xff0c;北卡罗来纳州立大学在读博士生—唐圣坤与浙江大学硕士生—张磊的Talk将准时在TechBeat人工智能社区开播&#xff01; 他们与大家分享的主题是: “数据为中心的高效视觉语言学习…

基于jsp+mysql+mybatis的SpringBoot美容院后台管理系统

运行环境: 最好是java jdk 1.8&#xff0c;我在这个平台上运行的。其他版本理论上也可以。 IDE环境&#xff1a; Eclipse,Myeclipse,IDEA或者Spring Tool Suite都可以&#xff0c;如果编译器的版本太低&#xff0c;需要升级下编译器&#xff0c;不要弄太低的版本 tomcat服务器环…

【嵌入式环境下linux内核及驱动学习笔记-(15)linux总线、设备、驱动模型之I2C总线】

目录 1、 I2C总线机制1.1 导入1.2 时序1.3 地址格式 2、华清fs4412上I2C的实现2.1 寄存器2.2 寄存器位具体含义2.3 fs4412上针对具本设备的I2C工作逻辑2.3.1 主机读写工作流程**2.3.1.1 主机发送时序及操作流程2.3.1.2 主机接收的时序及流程 2.3.2 从机读写工作流程 3、LINUX内…

Redis-认识NoSQl和Redis常见的通用命令

1. 认识NoSQL 非关系型数据库 NoSQL是指一类非关系型数据库&#xff0c;它们采用的数据模型不同于传统的关系模型&#xff0c;它通常使用键值对、文档、图形等非传统的数据结构进行数据存储&#xff0c;不遵循预定义的模式和模型。NoSQL数据库通常分布式、高可扩展性&#xff0…

【项目一】GCC(gcc,g++)、静态库、动态库、MakeFile、GDB调试

GCC、静态库 1.2 GCC(1&#xff09;gcc&#xff08;1&#xff09;常用命令&#xff08;2&#xff09; C程序编译过程&#xff08;3&#xff09;GCC工作流程 1.3 GCC(2&#xff09;g1.3静态库的制作1.5静态库的使用1.6动态库的制作1.7动态库加载失败的原因1.8解决动态库加载失败…

秋招必看,Java后端高频面试题1000题、拒绝简单背诵,深入浅出近30个技术栈

Java 面试随着时间的改变而改变。在过去的日子里&#xff0c;当你知道 String 和 StringBuilder 的区别就能让你直接进入第二轮面试&#xff0c;但是现在问题变得越来越高级&#xff0c;面试官问的问题也更深入。 在我初入职场的时候&#xff0c;类似于 Vector 与 Array 的区别…

面试专题:计算机网络常见面试点总结

socket、tcp、udp、http 的认识及区别 socket、tcp、udp、http 的认识及区别​ 一、先来一个讲TCP、UDP和HTTP关系的 1、TCP/IP是个协议组&#xff0c;可分为三个层次&#xff1a;网络层、传输层和应用层。 在网络层有IP协议、ICMP协议、ARP协议、RARP协议和BOOTP协议。 在传…

10分钟让你彻底了解Loadrunner性能测试工具

目录 Loadrunner简介 Loadrunner原理 Loadrunner工具组件 1、VUGen&#xff08;虚拟用户生成器&#xff09; 2、Controller&#xff08;控制器&#xff09; 3、Load Generator&#xff08;负载生成器&#xff09; 4、Analysis分析器 性能测试工具&#xff0c;从广义上讲…

Shell脚本攻略:Linux防火墙

目录 一、理论 1.安全技术 2.防火墙 3.通信五元素和四元素 二、实验 1.iptables基本操作 2.扩展匹配 一、理论 1.安全技术 &#xff08;1&#xff09;安全技术 ①入侵检测系统&#xff08;Intrusion Detection Systems&#xff09;&#xff1a;特点是不阻断任何网络访…

游戏外包开发技术难点分析

游戏开发涉及多个领域的技术&#xff0c;因此在开发过程中可能会遇到很多技术难点。今天和大家分享一些常见的游戏开发技术难点&#xff0c;希望对大家开发游戏有一定帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1. 图形渲染…

「料见」vol25.回顾 | PKU-Beaver开源项目团队:一起来聊首个可复现的RLHF基准

为了解决复现RLHF技术和基于RLHF技术的大预言模型的不安全问题&#xff0c;北京大学团队开源了名为PKU-Beaver&#xff08;海狸&#xff09;开源项目。 第25期料见闭门分享会&#xff0c;我“门”非常开心邀请到PKU-Beaver开源项目团队成员——北京大学人工智能研究院助理教授…

欧美同学会第三届“双创”大赛——空天装备产业赛区(浙江诸暨)正式启动,开启报名通道

6月8日&#xff0c;欧美同学会第三届“双创”大赛——空天装备产业赛区&#xff08;浙江诸暨&#xff09;启动仪式暨北京推介会圆满举行。活动由欧美同学会&#xff08;中国留学人员联谊会&#xff09;主办&#xff0c;中共浙江省委统战部支持&#xff0c;浙江省欧美同学会、中…

国内比较火的报表工具测评——Smartbi电子表格软件和Finereport

最近在学习BI软件&#xff0c;因为最近工作中需要开发报表&#xff0c;因此选用了国内市场比较热门的报表工具——Finereport和Spreadsheet进行学习。 BI软件经常会定期发布新的版本&#xff0c;增加新的功能模块&#xff0c;或者对现有功能进行增强&#xff0c;提升运行效率。…