vue实现二维码生成器和解码器

vue实现二维码生成器和解码器

1.生成基本二维码:根据输入的value生成二维码。
2.可定制尺寸:通过size调整大小。
3.颜色和背景色:设置二维码颜色和背景。
4.静区(quiet zone)支持:通过quietZone调整周围的空白区域。
5.错误纠正级别:ecl参数控制容错级别。
6.渐变效果:启用线性渐变,可以自定义方向和颜色。
7.Logo嵌入:在二维码中间添加logo,可调整大小、边距、背景色和圆角。
8.错误处理:生成失败时显示错误信息。
9.响应式更新:当props变化时自动重新生成二维码。
10.视图框调整:根据静区计算viewBox,确保正确显示。

效果图:
在这里插入图片描述

step1: 添加依赖 npm install qrcode @types/qrcode

step2:核心组件 实现二维码
C:\Users\wangrusheng\PycharmProjects\untitled3\src\views\QrCode.vue

<template><!-- SVG 容器 --><svgv-if="!error":viewBox="viewBox":width="size":height="size"><!-- 背景 --><rect:x="-quietZone":y="-quietZone":width="size + quietZone * 2":height="size + quietZone * 2":fill="backgroundColor"/><!-- 渐变定义 --><defs v-if="enableLinearGradient"><linearGradientid="grad":x1="gradientDirection[0]":y1="gradientDirection[1]":x2="gradientDirection[2]":y2="gradientDirection[3]"><stop offset="0" :stop-color="linearGradient[0]" stop-opacity="1"/><stop offset="1" :stop-color="linearGradient[1]" stop-opacity="1"/></linearGradient></defs><!-- 二维码路径 --><path:d="path"stroke-linecap="butt":stroke="enableLinearGradient ? 'url(#grad)' : color":stroke-width="cellSize"/><!-- Logo 容器 --><svgv-if="logo":x="(size - logoSize - logoMargin * 2) / 2":y="(size - logoSize - logoMargin * 2) / 2"><!-- Logo 背景 --><rect:width="logoSize + logoMargin * 2":height="logoSize + logoMargin * 2":fill="logoBackgroundColor":rx="logoBorderRadius + (logoMargin / logoSize) * logoBorderRadius":ry="logoBorderRadius + (logoMargin / logoSize) * logoBorderRadius"/><!-- Logo 图片 --><image:x="logoMargin":y="logoMargin":width="logoSize":height="logoSize":href="logo"preserveAspectRatio="xMidYMid slice":rx="logoBorderRadius":ry="logoBorderRadius"/></svg></svg><!-- 错误显示 --><div v-if="error" class="error">{{ error.message }}</div>
</template><script setup lang="ts">
import { ref, watchEffect, computed } from 'vue'
import QRCode from 'qrcode'// Props 定义
const props = defineProps({value: { type: String, default: 'this is a QR code' },size: { type: Number, default: 100 },color: { type: String, default: 'black' },backgroundColor: { type: String, default: 'white' },logo: { type: String, default: undefined },logoSize: { type: Number, default: 100 * 0.2 }, // 默认基于 size 计算logoBackgroundColor: { type: String, default: 'transparent' },logoMargin: { type: Number, default: 2 },logoBorderRadius: { type: Number, default: 0 },quietZone: { type: Number, default: 0 },enableLinearGradient: { type: Boolean, default: false },gradientDirection: {type: Array as () => string[],default: () => ['0%', '0%', '100%', '100%']},linearGradient: {type: Array as () => string[],default: () => ['rgb(255,0,0)', 'rgb(0,255,255)']},ecl: { type: String as () => 'L'|'M'|'Q'|'H', default: 'M' }
})// 响应式数据
const path = ref('')
const cellSize = ref(0)
const error = ref<Error | null>(null)// 生成二维码矩阵
const genMatrix = (value: string, errorCorrectionLevel: string): boolean[][] => {const arr = Array.prototype.slice.call(QRCode.create(value, { errorCorrectionLevel }).modules.data, 0)const sqrt = Math.sqrt(arr.length)return arr.reduce((rows: boolean[][], key: boolean, index: number) => {(index % sqrt === 0) ? rows.push([key]) : rows[rows.length - 1].push(key)return rows}, [])
}// 转换矩阵为 SVG 路径
const transformMatrixIntoPath = (matrix: boolean[][], size: number) => {const cellSize = size / matrix.lengthlet path = ''matrix.forEach((row, i) => {let needDraw = falserow.forEach((column, j) => {if (column) {if (!needDraw) {path += `M${cellSize * j} ${cellSize / 2 + cellSize * i} `needDraw = true}if (needDraw && j === matrix.length - 1) {path += `L${cellSize * (j + 1)} ${cellSize / 2 + cellSize * i} `}} else {if (needDraw) {path += `L${cellSize * j} ${cellSize / 2 + cellSize * i} `needDraw = false}}})})return { cellSize, path }
}// 计算 viewBox
const viewBox = computed(() => [-props.quietZone,-props.quietZone,props.size + props.quietZone * 2,props.size + props.quietZone * 2
].join(' '))// 监听 props 变化
watchEffect(() => {try {const matrix = genMatrix(props.value, props.ecl)const result = transformMatrixIntoPath(matrix, props.size)path.value = result.pathcellSize.value = result.cellSizeerror.value = null} catch (err) {error.value = err instanceof Error ? err : new Error('QR Code generation failed')}
})
</script><style scoped>
.error {color: red;border: 1px solid red;padding: 1rem;
}
</style>

step3: 调用二维码组件
C:\Users\wangrusheng\PycharmProjects\untitled3\src\views\ImgCode.vue

<template><QrCode:value="qrCodeValue":size="200"color="#333"logo="/logo.png":logo-size="40"logo-background-color="white":enable-linear-gradient="true"/>
</template><script setup>
import QrCode from './QrCode.vue'
import { ref } from 'vue'
// 图片资源存放在 C:\Users\wangrusheng\PycharmProjects\untitled3\public\logo.png
// JSON.stringify() 是 JavaScript 中用于将对象或值转换为 JSON 格式字符串的核心方法,
//value="你们好,这里是二维码识别器,很高兴认识你们"
const qrCodeValue = ref(JSON.stringify({"data": [{"case_id": 3,"category_id": 4,"title": "as","description": "ad","price": 4500.0,"client_id": 5,"lawyer_id": 6,"status": "pending","created_at": "2025-03-21T06:11:59","updated_at": "2025-03-21T06:11:59","category_name": "af"},{"case_id": 8,"category_id": 8,"title": "bs","description": "bd","price": 6000.0,"client_id": 5,"lawyer_id": 6,"status": "in_progress","created_at": "2025-03-21T06:11:59","updated_at": "2025-03-21T06:11:59","category_name": "bf"}]
}))
</script>

step4:路由

C:\Users\wangrusheng\PycharmProjects\untitled3\src\router\index.js
import ImgCode from '../views/ImgCode.vue'
{ path: '/imgcode', name: 'imgcode', component: ImgCode },C:\Users\wangrusheng\PycharmProjects\untitled3\src\App.vue
<router-link to="/imgcode" active-class="active-link">二维码</router-link>

///我是分割线
解码部分
step101:安装依赖 pip install pyzbar Pillow,你去网站上,随便找个二维码生成器,然后将生成的二维码保存本地

step102:解析C:\Users\wangrusheng\PycharmProjects\FastAPIProject1\hello.py

from pyzbar.pyzbar import decode
from PIL import Image# 二维码图片路径 C:\Users\wangrusheng\Downloads
old_file = r'C:\Users\wangrusheng\Downloads\logoz.png'try:# 打开图片文件with Image.open(old_file) as img:# 解析二维码decoded_objects = decode(img)if not decoded_objects:print("未检测到二维码内容。")else:for obj in decoded_objects:# 解码数据(假设内容为UTF-8文本)data = obj.data.decode('utf-8')print("解析结果:", data)except FileNotFoundError:print(f"错误:文件 '{old_file}' 不存在。")
except Exception as e:print(f"解析时发生错误: {str(e)}")

step103:运行

(.venv) PS C:\Users\wangrusheng\PycharmProjects\FastAPIProject1> python hello.py 
解析结果: 能不能点点赞  点点关注,我谢谢大家
(.venv) PS C:\Users\wangrusheng\PycharmProjects\FastAPIProject1> 

end

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

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

相关文章

Nacos:Nacos服务注册与服务发现超详细的源码解析(二)

&#x1fa81;&#x1f341; 希望本文能给您带来帮助&#xff0c;如果有任何问题&#xff0c;欢迎批评指正&#xff01;&#x1f405;&#x1f43e;&#x1f341;&#x1f425; 文章目录 一、背景二、环境与依赖三、服务注册与服务发现总流程图四、服务注册源码4.1 客户端4.1.1…

ECMAScript 6 新特性(二)

ECMAScript 6 新特性&#xff08;二&#xff09; ECMAScript 6 新特性&#xff08;一&#xff09; ECMAScript 6 新特性&#xff08;二&#xff09;&#xff08;本文&#xff09; ECMAScript 7~10 新特性 1. 生成器 生成器函数是 ES6 提供的一种解决异步编程方案&#xff0c;一…

深入理解 RxSwift 中的 Driver:用法与实践

目录 前言 一、什么是Driver 1.不会发出错误 2.主线程保证 3.可重放 4.易于绑定 二、Driver vs Observable 三、使用场景 1.绑定数据到UI控件 2.响应用户交互 3.需要线程安全的逻辑 4.如何使用Driver? 1.绑定文本输入到Label 2.处理按钮点击事件 3.从网络请求…

Linux自行实现的一个Shell(15)

文章目录 前言一、头文件和全局变量头文件全局变量 二、辅助函数获取用户名获取主机名获取当前工作目录获取最后一级目录名生成命令行提示符打印命令行提示符 三、命令处理获取用户输入解析命令行执行外部命令 四、内建命令添加环境变量检查和执行内建命令 五、初始化初始化环境…

RocketMQ和kafka 的区别

一、数据可靠性与容错机制 数据可靠性 RocketMQ支持同步刷盘和同步复制&#xff0c;确保消息写入磁盘后才返回确认&#xff0c;单机可靠性高达10个9&#xff0c;即使操作系统崩溃也不会丢失数据。而Kafka默认采用异步刷盘和异步复制&#xff0c;虽然吞吐量高&#xff0c;但极端…

在 openEuler 24.03 (LTS) 操作系统上添加 ollama 作为系统服务的步骤

以下是在 openEuler 操作系统上添加 ollama 作为系统服务的步骤&#xff1a; 创建 systemd 服务文件 sudo vi /etc/systemd/system/ollama.service将以下内容写入服务文件&#xff08;按需修改参数&#xff09;&#xff1a; [Unit] DescriptionOllama Service Afternetwork.…

光谱相机的关键技术参数

光谱相机的关键技术参数直接影响其数据获取能力和应用场景适配性。以下是核心参数的详细解析&#xff0c;涵盖光谱性能、空间性能、硬件性能及环境适应性&#xff1a; 一、光谱性能参数‌ ‌1. 光谱范围&#xff08;Spectral Range&#xff09;‌ ‌定义‌&#xff1a;相机可…

ARM内核与寄存器

ARM内核与寄存器详解 目录 ARM架构概述ARM处理器模式 Cortex-M3内核的处理器模式Cortex-A系列处理器模式 ARM寄存器集 通用寄存器程序计数器(PC)链接寄存器(LR)堆栈指针(SP)状态寄存器(CPSR/SPSR) 协处理器寄存器NEON和VFP寄存器寄存器使用规范常见ARM指令与寄存器操作 ARM架…

Git 拉取时常见冲突及解决方法总结

Git 拉取时常见冲突及解决方法总结 一、常见错误场景1. 本地修改与远程修改冲突解决方法 2. 未跟踪文件与远程文件冲突解决方法 3. 子模块权限问题解决方法 二、总结 在日常开发中&#xff0c;使用 Git 进行团队协作和代码管理时&#xff0c;经常会遇到拉取代码&#xff08;git…

深度学习、图像算法学习记录

深度学习加速 综述文档&#xff1a; https://chenzomi12.github.io/02Hardware01Foundation/02ArchSlim.html winograd: https://zhuanlan.zhihu.com/p/260109670 ncnn 1.修改模型结构&#xff0c;优化模型内存访问次数&#xff0c;加速。 VGG 和 InceptionNet &#xff1a; …

Java中的Exception和Error有什么区别?还有更多扩展

概念 在Java中&#xff0c;Exception和Error都是Throwable的子类&#xff0c;用于处理程序中的错误和异常情况。 然而&#xff0c;它们在用途和处理方式上有显著的不同&#xff1a; Exception&#xff1a; 用于表示程序在正常运行过程中可能出现的错误&#xff0c;如文件未找…

文章记单词 | 第26篇(六级)

一&#xff0c;单词释义 actor&#xff1a;名词&#xff0c;演员mask&#xff1a;名词&#xff0c;面具&#xff1b;口罩&#xff1b;遮盖物&#xff1b;动词&#xff0c;掩饰&#xff1b;戴面具&#xff1b;遮盖construct&#xff1a;动词&#xff0c;建造&#xff1b;构造&a…

LeetCode算法题(Go语言实现)_38

题目 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 一、代码实现 type TreeNode struct {Val intLeft *TreeNodeRight *TreeNode }func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {if root nil || root p || root q {return root}left : lowes…

Java 基础语法、Java注释

Java 基础语法 一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念。 对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫…

用VScode来编写前后端——构建基础框架

前言 我写这一个板块的原因是我参加了我们学校的新生项目课&#xff0c;需要创立一个系统&#xff0c;我们小组选的标题的基于计算机视觉的商品识别系统&#xff0c;那么我们需要一个网站来展示我们的功能&#xff0c;故写这些来记录一下自己&#xff0c;大家如果有什么问题的话…

git clone阻塞问题

问题描述 git clone采用的ssh协议&#xff0c;在克隆仓库的时候&#xff0c;会经常卡一下&#xff0c;亦或是直接卡死不动。 最开始以为是公司电脑配置的问题&#xff0c;想着自己实在解决不了找it帮忙。 查阅资料发现&#xff0c;最终发现是git版本的问题&#xff0c;这个是…

WEB攻防-Java安全JNDIRMILDAP五大不安全组件RCE执行不出网不回显

目录 1. RCE执行-5大类函数调用 1.1 Runtime方式 1.2 Groovy执行命令 1.3 脚本引擎代码注入 1.4 ProcessImpl 1.5 ProcessBuilder 2. JNDI注入(RCE)-RMI&LDAP&高版本 2.1 RMI服务中的JNDI注入场景 2.2 LDAP服务中的JNDI注入场景 攻击路径示例&#…

【Hadoop入门】Hadoop生态之Sqoop简介

1 什么是Sqoop&#xff1f; 在企业的数据架构中&#xff0c;关系型数据库与Hadoop生态系统之间的数据流动是常见且关键的需求。Apache Sqoop&#xff08;SQL-to-Hadoop&#xff09;正是为解决这一问题而生的高效工具&#xff0c;它专门用于在结构化数据存储&#xff08;如RDBMS…

如何自动检测使用的组件库有更新

&#x1f916; 作者简介&#xff1a;水煮白菜王&#xff0c;一位前端劝退师 &#x1f47b; &#x1f440; 文章专栏&#xff1a; 前端专栏 &#xff0c;记录一下平时在博客写作中&#xff0c;总结出的一些开发技巧和知识归纳总结✍。 感谢支持&#x1f495;&#x1f495;&#…

Go语言编写一个进销存Web软件的demo

Go语言编写一个进销存Web软件的demo 用户现在要求用。之前他们已经讨论了用Django实现的方案&#xff0c;现在突然切换到Go&#xff0c;可能有几个原因。首先&#xff0c;用户可能对Go语言感兴趣&#xff0c;或者他们公司的技术栈转向了Go。其次&#xff0c;用户可能希望比较不…