微信小程序-二维码绘制

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'});},});}
});

引入文件

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

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

相关文章

Linux系统中ssh远程登录协议

目录 一、SSH协议概述 二、SSH协议工作原理 三、ssh服务与配置文件 3.1、openssh 3.2、ssh命令 3.3、服务端配置 四、基于密钥验证的免交互登录 4.1、客户端生成密钥 4.2、将公钥拷贝至服务器 4.3、验证免密登录 一、SSH协议概述 SSH&#xff08;Secure Shell&#x…

vue2 ruoyi websocket轮询

文章目录 前言一、websocket和心跳是什么&#xff1f;二、使用步骤1.2.监听变化3.关闭 总结 前言 websocket&#xff0c;实现与后端通讯&#xff0c;使用心跳机制&#xff0c;断联自动恢复。 一、websocket和心跳是什么&#xff1f; WebSocket WebSocket 是一种网络通信协议&a…

LangChain大模型应用开发:LangGraph快速构建Agent工作流应用

介绍 大家好&#xff0c;博主又来给大家分享知识了。今天给大家分享的内容是使用LangChain进行大规模应用开发中的LangGraph快速构建Agent工作流应用。 通过对前几次对LangChain的技术分享。我们知道LangChain作为一个强大的工具集&#xff0c;为开发者们提供了丰富的资源和便…

学习FreeRTOS推荐几篇质量高的文章

学习FreeRTOS是一个非常好的选择&#xff0c;因为它是一个广泛使用的实时操作系统&#xff08;RTOS&#xff09;&#xff0c;特别适合嵌入式系统开发。以下是一些高质量的文章和视频资源&#xff0c;帮助你入门和深入学习FreeRTOS&#xff1a; 文章推荐 FreeRTOS官方文档 链接…

深入理解Redis:数据类型、事务机制及其应用场景

在当今快速发展的技术领域中&#xff0c;Redis作为一种高性能的内存数据库&#xff0c;已经被广泛应用于各种场景&#xff0c;从简单的缓存实现到复杂的数据处理任务。其灵活性和高效性主要来源于对多种数据结构的支持以及强大的功能特性&#xff0c;如事务处理、持久化选项、高…

k8s集群3主5从高可用架构(kubeadm方式安装k8s)

关键步骤说明 环境准备阶段 系统更新&#xff1a;所有节点执行yum/apt update确保软件包最新时间同步&#xff1a;通过ntpdate time.windows.com或部署NTP服务器网络规划&#xff1a;明确划分Service网段&#xff08;默认10.96.0.0/12&#xff09;和Pod网段&#xff08;如Flann…

Dify部署无法拉取镜像

Dify部署无法摘取镜像 sudo docker compose up -d [] Running 10/10✘ nginx Error Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiti... 15.2s✘ we…

科技快讯 | L3自动驾驶之风吹向全球 2025年或成商业化关键;DeepSeek商标遭恶意抢注

消息称AMD拟以40亿美元出售数据中心工厂&#xff0c;部分台企成潜在买家 2月24日&#xff0c;彭博社报道&#xff0c;AMD正与包括台湾广达电子、英业达、和硕联合以及纬创资通在内的亚洲企业谈判&#xff0c;出售其去年收购的数据中心制造工厂&#xff0c;总价值可能在30-40亿美…

06C语言——指针

一、指针入门 (1)、准备知识 0、图解&#xff1a; 1、内存地址 字节&#xff1a;字节是内存的容量单位&#xff0c;英文称为 byte&#xff0c;一个字节有8位&#xff0c;即 1byte(0000 0000 --- 1111 1111) 8bits(0 --- 1) 地址&#xff1a;系统为了便于区分每一个字节而对…

Python爬虫selenium验证-中文识别点选+图片验证码案例

1.获取图片 import re import time import ddddocr import requests from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.service import Service from selenium.webdriver.support.wait import WebDriverWait from …

OpenCV(6):图像边缘检测

图像边缘检测是计算机视觉和图像处理中的一项基本任务&#xff0c;它用于识别图像中亮度变化明显的区域&#xff0c;这些区域通常对应于物体的边界。是 OpenCV 中常用的边缘检测函数及其说明: 函数算法说明适用场景cv2.Canny()Canny 边缘检测多阶段算法&#xff0c;检测效果较…

电子科技大学考研复习经验分享

电子科技大学考研复习经验分享 本人情况&#xff1a;本科就读于电科软院&#xff0c;24年2月开始了解考研&#xff0c;24年3月开始数学&#xff0c;9月决定考本院&#xff08;开始全天候图书馆学习&#xff09;并开始专业课学习&#xff0c;11月底开始政治学习&#xff0c;最后…

go基础语法

go基础语法 先下载安装go&#xff0c;然后到vscode下载go插件 1. 基础 输入输出 package main import "fmt" func main(){a:1var b2 var c int //不给初始值得标出变量类型 c3var d stringfmt.Scanf("%s",&d) //接收用户输入fmt.Printf("Hell…

硬件基础(3):三极管(1):理论基础

目录 一、背景 二、定义 三、分类 四、工作原理 NPN三极管工作原理 基本工作原理 电流放大倍数&#xff08;增益&#xff09; 输入特性 1. 输入特性的基本概念 2. 输入特性曲线的形态 3. 输入特性曲线的具体分析 输出特性 1. 输出特性图的基本概念 2. 输出特性曲…

Git最佳实践指南(Windows/Linux双系统详解)

Git最佳实践指南&#xff1a;从入门到熟练&#xff08;Windows/Linux双系统详解&#xff09; 一、环境搭建与基础配置&#xff08;适用Windows/Linux&#xff09; 1.1 Git安装与验证 # Windows系统安装&#xff08;推荐Chocolatey包管理&#xff09; # 直接下载git二进制文件…

吃一堑长一智

工作中经历&#xff0c;有感触记录下 故事一 以前在一家公司时&#xff0c;自己是一名开发人员&#xff0c;遇到问题请教领导解决方案&#xff0c;当时领导给了建议&#xff0c;后来上线后出问题了&#xff0c;背了锅。心里想的是领导说这样做的呀&#xff0c;为什么出问题还…

联想 SR590 服务器 530-8i RAID 控制器更换损坏的硬盘

坏了的硬盘会自动亮黄灯。用一个空的新盘来替换&#xff0c;新盘最好不要有东西。但是有东西可能也没啥&#xff0c;因为我看 RAID 控制器里有格式化的选项 1. 从 IPMI 把服务器关机&#xff0c;电源键进入绿色闪烁状态 2. 断电&#xff0c;推开塑料滑块拉出支架&#xff0c;…

前端浏览器开发中的浏览器兼容问题【持续更新】

目录 一、什么是浏览器兼容问题 二、JavaScript兼容问题及解决方案 2.1addEventListener与attachEvent的区别 2.2集合类对象问题 2.3自定义属性问题 2.4event.x与event.y问题 2.5window.location.href问题 2.6事件委托方法 三、CSS兼容问题及解决方案 3.1浏览器CSS样式初…

【c语言】字符函数和字符串函数(1)

一、字符分类函数 c语言中有部分函数是专门做字符分类的&#xff0c;也就是一个字符是属于什么类型的字符&#xff0c;这些函 数的使用要包含一个头文件ctype.h中。 其具体如下图所示&#xff1a; 这些函数的使用方式都类似&#xff0c;下面我们通过一个函数来看其…

LeetCodehot 力扣热题100 全排列

这段代码的目的是计算给定整数数组的所有全排列&#xff08;permutations&#xff09;&#xff0c;并返回一个包含所有排列的二维数组。 思路解析 在这段代码中&#xff0c;采用了 深度优先搜索&#xff08;DFS&#xff09; 和 回溯 的方法来生成所有的排列。 关键步骤&#xf…