当前位置: 首页 > news >正文

微信小程序-二维码绘制

wxml

<view bindlongtap="saveQrcode"><!-- 二维码 --><view style="position: absolute;background-color: #FFFAEC;width: 100%;height: 100vh;"><canvas canvas-id="myQrcode" style="width: 200px; height: 200px;background-color: azure;position: fixed;top: 999px;" ></canvas></view><!-- 绘制的背景图 --><canvas type="2d" id="newQrcode" style="width: 100%;height: 700px;z-index: 99;"></canvas>
</view>

wxss

/* pages/QRcode/QRcode.wxss */
.canvas {width: 100%;height: -webkit-calc(100% - 44px);height: -moz-calc(100% - 44px);height: calc(100% - 44px);background: #fff;}

js

// pages/index/index.js
import QRCode from './weapp.qrcode.esm';let textCanvas;Page({data: {qrcodeVisible: true // 控制二维码是否显示},onReady() {// 等待二维码绘制完成后再获取临时文件路径this.generateQRCode().then((tempQrcodePath) => {this.drawCompositeImage(tempQrcodePath);}).catch((err) => {console.error('生成二维码临时文件失败:', err);wx.showToast({title: '生成二维码临时文件失败',icon: 'none'});});},// 生成二维码并获取临时文件路径generateQRCode() {return new Promise((resolve, reject) => {// 初始化二维码QRCode({width: 200,height: 200,canvasId: 'myQrcode',colorDark: '#000000',colorLight: '#ffffff',text: 'http://lxj.yzwdblzs.xyz/',});// 延迟一段时间确保二维码绘制完成,可根据实际情况调整延迟时间setTimeout(() => {wx.canvasToTempFilePath({canvasId: 'myQrcode',success: (res) => {console.log('二维码路径:', res);const tempQrcodePath = res.tempFilePath;resolve(tempQrcodePath);},fail: (err) => {console.error('获取临时文件失败', err);reject(err);}});}, 500);});},drawCompositeImage(tempQrcodePath) {return new Promise((resolve, reject) => {wx.createSelectorQuery().select('#newQrcode').fields({node: true,size: true}).exec((res) => {textCanvas = res[0].node; // 获取 canvas 节点const textCtx = textCanvas.getContext('2d');const dpr = wx.getSystemInfoSync().pixelRatio; // 获取设备像素比textCanvas.width = res[0].width * dpr;textCanvas.height = res[0].height * dpr;textCtx.scale(1, 1);textCtx.fillRect(0, 0, 200, 200);textCtx.clearRect(0, 0, textCanvas.width, textCanvas.height);textCtx.beginPath();const bg = textCanvas.createImage();bg.src = 'http://lxj.yzwdblzs.xyz/img/noName.png';bg.onload = () => {console.log('背景图加载成功');const qrImage = textCanvas.createImage();qrImage.src = tempQrcodePath;qrImage.onload = () => {console.log('二维码加载成功');// 绘制背景图this.drawBackground(textCtx, bg);// 绘制二维码this.drawQRCode(textCtx, tempQrcodePath);resolve();};qrImage.onerror = () => {console.error('二维码加载失败');reject(new Error('二维码加载失败'));};};bg.onerror = () => {console.error('背景图加载失败');reject(new Error('背景图加载失败'));};});});},drawBackground(textCtx, bg) {const bgWidth = bg.width;const bgHeight = bg.height;// 计算缩放比例const scaleX = textCanvas.width / bgWidth;const scaleY = textCanvas.height / bgHeight;const scale = Math.max(scaleX, scaleY); // 选择最大的比例以适应 canvas// 计算背景图绘制的尺寸const drawWidth = bgWidth * scale;const drawHeight = bgHeight * scale;// 绘制背景图textCtx.drawImage(bg, 0, 0, drawWidth, drawHeight);},drawQRCode(textCtx, tempQrcodePath) {const qrWidth = 550; // 二维码宽度const qrHeight = 550; // 二维码高度const qrX = (textCanvas.width - qrWidth + 40) / 2; // 水平居中const qrY = (textCanvas.height - qrHeight + 940) / 2; // 垂直居中// 绘制二维码到背景图上const qrImage = textCanvas.createImage();qrImage.src = tempQrcodePath;qrImage.onload = () => {textCtx.drawImage(qrImage, qrX, qrY, qrWidth, qrHeight);// 合成图像成功后隐藏二维码this.setData({qrcodeVisible: false});};qrImage.onerror = () => {console.error('二维码绘制失败');};},// 长按保存// 最终合成图像保存到临时路径saveQrcode() {wx.getSetting({success: (res) => {if (!res.authSetting['scope.writePhotosAlbum']) {wx.authorize({scope: 'scope.writePhotosAlbum',success: () => {this.saveCanvasToAlbum();},fail: (err) => {console.error('用户拒绝授权保存相册', err);wx.showToast({title: '未授权保存相册',icon: 'none'});}});} else {this.saveCanvasToAlbum();}}});},saveCanvasToAlbum() {wx.showLoading({title: '正在保存图片...',});wx.canvasToTempFilePath({canvas: textCanvas,success: (finalRes) => {wx.saveImageToPhotosAlbum({filePath: finalRes.tempFilePath,success: () => {wx.hideLoading();wx.showToast({title: '保存成功',});},fail: (err) => {wx.hideLoading();console.error('保存失败', err);wx.showToast({title: '保存失败',icon: 'none'});},});},fail: (err) => {wx.hideLoading();console.error('合成图像失败', err);wx.showToast({title: '合成图像失败',icon: 'none'});},});}
});

引入文件

相关文章:

微信小程序-二维码绘制

wxml <view bindlongtap"saveQrcode"><!-- 二维码 --><view style"position: absolute;background-color: #FFFAEC;width: 100%;height: 100vh;"><canvas canvas-id"myQrcode" style"width: 200px; height: 200px;ba…...

轻量化网络设计|ShuffleNet:深度学习中的轻量化革命

一、引言 在深度学习中&#xff0c;卷积神经网络&#xff08;Convolutional Neural Networks&#xff0c;CNN&#xff09;无疑是大家最耳熟能详的算法之一。自诞生以来&#xff0c;CNN 在图像分类、目标检测、语义分割等众多计算机视觉任务中取得了令人瞩目的成就&#xff0c;…...

一天记20个忘10个之五:land

一天记20个忘10个之五&#xff1a;land land n.陆地&#xff0c;土地 v.着陆&#xff0c;降落 // la-拉、宽广 nd后缀 字面义&#xff1a;宽广的土地 陆地 landing n.着陆&#xff0c;降落lander n.登陆车&#xff0c;着陆者 派生&#xff1a; island岛,岛屿 //isle(n.用于…...

Python 类(创建和使用类)

面向对象编程 是最有效的软件编写方法之一。在面向对象编程中&#xff0c;你编写表示现实世界中的事物和情景的类&#xff0c;并基于这些类来创建对象。编写类时&#xff0c;你定义一大类对 象都有的通用行为。基于类创建对象 时&#xff0c;每个对象都自动具备这种通用行为&am…...

LeetCode 解题思路 3(Hot 100)

解题思路&#xff1a; 初始化指针&#xff1a; 左指针指向数组起始位置&#xff0c;右指针指向数组末尾。计算当前面积&#xff1a; 左右指针相遇前所围成的矩形面积。​更新最大面积&#xff1a; 比较当前面积与已知最大面积。​移动指针&#xff1a; 移动较高指针无法获得更…...

算法-二叉树篇11-左叶子之和

左叶子之和 力扣题目链接 题目描述 给定二叉树的根节点 root &#xff0c;返回所有左叶子之和。 解题思路 层次遍历的时候&#xff0c;保留每层第一个节点并相加即可。 题解 class Solution { public:int sumOfLeftLeaves(TreeNode* root) {if(root NULL){return 0;}re…...

MaxKB上架至阿里云轻量应用服务器镜像市场

近日&#xff0c;MaxKB开源知识库问答系统已上架至阿里云轻量应用服务器镜像市场&#xff0c;目前是阿里云此类镜像市场中唯一推荐的AI应用镜像。 ▲图1 MaxKB已经上架至阿里云轻量应用服务器镜像市场 MaxKB是飞致云旗下开源项目&#xff0c;是一款基于大语言模型和RAG&…...

用户态和内核态是什么?

用户态&#xff08;User Mode&#xff09;和内核态&#xff08;Kernel Mode&#xff09;。这两个概念是理解操作系统工作原理的基础。 1. 什么是用户态和内核态&#xff1f; 1.1 用户态&#xff08;User Mode&#xff09; 用户态是操作系统为普通应用程序提供的运行模式。在这…...

2025年SCI一区智能优化算法:混沌进化优化算法(Chaotic Evolution Optimization, CEO),提供MATLAB代码

一、混沌进化优化算法 https://github.com/ITyuanshou/MATLABCode 1. 算法简介 混沌进化优化算法&#xff08;Chaotic Evolution Optimization, CEO&#xff09;是2025年提出的一种受混沌动力学启发的新型元启发式算法。该算法的主要灵感来源于二维离散忆阻映射的混沌进化过…...

普中单片机-51TFT-LCD显示屏(1.8寸 STM32)

普中官方论坛&#xff1a; http://www.prechin.cn/gongsixinwen/208.html 普中科技-各型号开发板资料链接&#xff1a;https://www.bilibili.com/read/cv23681775/?spm_id_from333.999.0.0 27-TFTLCD显示实验_哔哩哔哩_bilibili 2.程序烧录 2.1设置彩屏驱动 3.实验效果...

SGMII(Serial Gigabit Media Independent Interface)详解

一、SGMII的定义与作用 SGMII&#xff08;串行千兆介质无关接口&#xff09;是一种用于千兆以太网&#xff08;1Gbps&#xff09;的串行接口标准&#xff0c;旨在通过减少引脚数量和简化设计&#xff0c;实现MAC层与PHY芯片之间的高速通信。其核心作用包括&#xff1a; 引脚精…...

DeepSeek:我的AI助手之旅

★【前言】: 初次使用AI助手帮我写作,就像摸石头过河一样,一点点的前行。我在慢慢的摸索,慢慢的体会中,感悟出的一点个人心得体会现分享给大家。这也说明一个问题,网站上各种使用方法和技巧是对于已经使用过的人来说的方便和快捷,但对于刚刚接触的使用者来说,网上的各…...

图片批量去重---(均值哈希、插值哈希、感知哈希、三/单通道直方图)

一、整体步骤 本脚本中&#xff0c;关键步骤包括以下步骤&#xff1a; 1、图片加载&#xff1a; 脚本会遍历指定的图片目录&#xff0c;将所有图片加载到内存中。 2、图像预处理&#xff1a; 比较之前&#xff0c;通常需要对图片进行预处理&#xff0c;如调整大小、灰度化或直方…...

Linux:(3)

一&#xff1a;Linux和Linux互传&#xff08;压缩包&#xff09; scp:Linux scp 命令用于 Linux 之间复制文件和目录。 scp 是 secure copy 的缩写, scp 是 linux 系统下基于 ssh 登陆进行安全的远程文件拷贝命令。 scp 是加密的&#xff0c;rcp 是不加密的&#xff0c;scp 是…...

vscode设置自动换行

vscode设置自动换行 方法 方法 点击文件->首选项->设置。搜索word wrap -> 选择 on 。 搜索Word Wrap&#xff0c;并把选项改为on。...

Instagram 隐私设置全面解析:如何保护你的个人数据?

Instagram 隐私设置全面解析&#xff1a;如何保护你的个人数据&#xff1f; 在这个数字化时代&#xff0c;社交媒体平台如 Instagram 已成为我们日常生活的一部分。然而&#xff0c;随着个人信息泄露和隐私侵犯事件的频发&#xff0c;保护个人数据变得尤为重要。本文将全面解析…...

Activiti 5 + Spring Boot全流程开发指南

目录 一、环境搭建&#xff08;Spring Boot 2.x&#xff09; 1.1 依赖配置 1.2 配置文件 二、流程定义与部署 2.1 创建BPMN文件&#xff08;leave.bpmn&#xff09; 2.2 流程部署服务 三、流程操作核心实现 3.1 启动流程实例 3.2 查询待办任务 四、审批流程处理 4.1 …...

spring结合mybatis多租户实现单库分表

实现单库分表 思路&#xff1a;student表数据量大&#xff0c;所以将其进行分表处理。一共有三个分表&#xff0c;分别是student0&#xff0c;student1&#xff0c;student2&#xff0c;在新增数据的时候&#xff0c;根据请求头中的meta-tenant参数决定数据存在哪张表表。 数…...

面向对象编程(OOP)基础:Java入门指南

引言 随着计算机技术的发展&#xff0c;软件的应用越来越复杂&#xff0c;单个程序的功能也逐渐增多。为了提高代码的复用性和可维护性&#xff0c;Java语言引入了**面向对象编程&#xff08;Object-Oriented Programming, OOP&#xff09;**这一设计理念。 OOP是一种设计程序…...

day7作业

编写一个如下场景&#xff1a; 有一个英雄Hero类&#xff0c;私有成员&#xff0c;攻击&#xff08;Atx&#xff09;&#xff0c;防御&#xff08;Defense&#xff09;&#xff0c;速度&#xff08;Speed)&#xff0c;生命值&#xff08;Blood)&#xff0c;以及所有的set get 方…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端&#xff08;即页面 JS / Web UI&#xff09;与客户端&#xff08;C 后端&#xff09;的交互机制&#xff0c;是 Chromium 架构中非常核心的一环。下面我将按常见场景&#xff0c;从通道、流程、技术栈几个角度做一套完整的分析&#xff0c;特别适合你这种在分析和改…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践

在 Kubernetes 集群中&#xff0c;如何在保障应用高可用的同时有效地管理资源&#xff0c;一直是运维人员和开发者关注的重点。随着微服务架构的普及&#xff0c;集群内各个服务的负载波动日趋明显&#xff0c;传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...