微信小程序使用canvas画图保存图片到手机相册

微信小程序要实现使用canvas绘制一个图,然后保存到手机相册

**最终效果:**实现生成以下图片在这里插入图片描述

一、初始化canvas

// wxml页面设置canvas标签
<canvas style="width: {{windowW}}px; height: {{windowH}}px;" disable-scroll='true' canvas-id="myCanvas" wx:if="{{showCanvas}}"></canvas>
// js页面初始化canvas
data: {ctx: '',details: '',windowW: 375*3,windowH: 265*3,ratio:3,showCanvas:false},onLoad(options) {this.setData({ctx: wx.createCanvasContext('myCanvas'),showCanvas:true})},

二、绘制canvas

// 绘制一个准考证并下载到手机相册
getsaves(){var that = this;let rat = 3;that.data.ctx.setFontSize(8*rat);that.data.ctx.setFillStyle('#080808');that.data.ctx.fillText('山东省第六届中小学生作文大赛决赛', 28*rat, 29*rat);that.data.ctx.setFontSize(8*rat);that.data.ctx.fillText('准考证', 81*rat, 59*rat);that.data.ctx.setFontSize(6*rat);that.data.ctx.fillText('考试时间:' + '10月18日(周五)上午9:00-11:00', 35*rat, 78*rat);that.data.ctx.fillText('考试地点:山东师范大学附属小学', 35*rat, 93*rat);that.data.ctx.fillText('济南市历下区山师北街1号', 66*rat, 104*rat);// that.data.ctx.fillText(that.data.details.cityName=='济南市'?'考试地点:山东师范大学附属小学':'考试地点:临沂商城实验学校', 26*rat, 93*rat);// that.data.ctx.fillText(that.data.details.cityName=='济南市'?'济南市历下区山师北街1号':'临沂市兰山区兰山街道工业大道59号', 56*rat, 104*rat);that.data.ctx.setFillStyle('#444444');that.data.ctx.fillText('准考证号', 43*rat, 128*rat);that.data.ctx.fillText('考生姓名', 43*rat, 144*rat);that.data.ctx.fillText('考生学校', 43*rat, 160*rat);that.data.ctx.fillText('考生组别', 43*rat, 176*rat);that.data.ctx.fillText('考场号', 43*rat, 192*rat);that.data.ctx.fillText('座位号', 43*rat, 208*rat);that.data.ctx.setFillStyle('#000000');that.data.ctx.fillText('2023005020340', 81*rat, 128*rat);that.data.ctx.fillText('张三', 81*rat, 144*rat);that.data.ctx.fillText('蒋庄矿区学校', 81*rat, 160*rat);that.data.ctx.fillText('初中组', 81*rat, 176*rat);that.data.ctx.fillText('--', 81*rat, 192*rat);that.data.ctx.fillText('--', 81*rat, 208*rat);that.data.ctx.setFillStyle('#080808');that.data.ctx.setFontSize(5*rat);that.data.ctx.fillText('请妥善保管,凭有效身份证件(身份证、户口本、护照、', 35*rat, 226*rat);that.data.ctx.fillText('社保卡、学生证等)入场考试。', 35*rat, 238*rat);that.data.ctx.setFontSize(8*rat);that.data.ctx.fillText('考生守则', 255*rat, 29*rat);const text1 = '     一、考生必须自觉服从监考员等考试工作人员管理,不得以任何理由妨碍监考员等考试工作人员履行职责,不得扰乱考场及其他考试工作地点的秩序。二、考生凭准考证、身份证(学生证、户口簿)按规定时间、地点参加考试。三、考生人场,除书写用0.5mm黑色签字笔外,其他任何物品不准带入考场。严禁携带各种通讯工具(如无线耳机、移动电话及其他无线接收、传送设备等)、手表、电子存储记忆录放设备以及涂改液、修正带等物品进人考场。考场内不得自行传递文具、用品等。四、考生入场后,对号入座,将准考证等证件放在课桌左上角以便核验,考生领到答题和试卷后,应检查答题卡和试卷是否有重印、漏印、字迹不清等印刷质量问题或缺页现象,如有,请立即举手报告,否则在开考一段时间后,考生如发现上述问题,由此延误的考试时不予弥补。考生应在指定位置和规定的时间内准确清楚地填写毕业学校、姓名准考证号、座号等栏目。五、开考信号发出后才能开始答题。六、开考15 分钟后不准人场。七、在考场内须保持安静,不准喧哗,不准交头接耳、左顾右盼,不准将试题、草稿纸带出考场。八、考试终了信号发出后,考生应立即停止答卷,并按试题、草稿纸自下而上的顺序排放好,坐在座位上,等候考员查收,无误后,根据监考员指令依次离开考场。九、如不遵守考场纪律,不服从考试工作人员管理,有违纪、作弊等行为的,将按照《国家教育考试违规处理办法》进行处理。';that.drawText(that.data.ctx, text1, 185*rat, 49*rat, 30*rat,165*rat); // 假设每行的最大宽度为300像素that.data.ctx.setStrokeStyle("#646464");that.data.ctx.setLineWidth(1);that.data.ctx.rect(35*rat, 118*rat, 127*rat, 96*rat);that.data.ctx.stroke()that.data.ctx.beginPath(); //创建一条路径   that.data.ctx.moveTo(35*rat, 133*rat); //描述路径的起点为手指触摸的x轴和y轴that.data.ctx.lineTo(162*rat, 133*rat); //绘制一条直线,终点坐标为手指触摸结束后的x轴和y轴that.data.ctx.moveTo(35*rat, 149*rat); //描述路径的起点为手指触摸的x轴和y轴that.data.ctx.lineTo(162*rat, 149*rat); //绘制一条直线,终点坐标为手指触摸结束后的x轴和y轴that.data.ctx.moveTo(35*rat, 165*rat); //描述路径的起点为手指触摸的x轴和y轴that.data.ctx.lineTo(162*rat, 165*rat); //绘制一条直线,终点坐标为手指触摸结束后的x轴和y轴that.data.ctx.moveTo(35*rat, 181*rat); //描述路径的起点为手指触摸的x轴和y轴that.data.ctx.lineTo(162*rat, 181*rat); //绘制一条直线,终点坐标为手指触摸结束后的x轴和y轴that.data.ctx.moveTo(35*rat, 197*rat); //描述路径的起点为手指触摸的x轴和y轴that.data.ctx.lineTo(162*rat, 197*rat); //绘制一条直线,终点坐标为手指触摸结束后的x轴和y轴that.data.ctx.moveTo(73*rat,118*rat);that.data.ctx.lineTo(73*rat, 214*rat); // 绘制一条直线到终点that.data.ctx.stroke();that.data.ctx.draw(true, function () {that.daochu();});
},

三、封装文字换行缩进

// 由于右侧文字较多,需要缩进和自动换行
drawText(ctx, str, leftWidth, initHeight, titleHeight, canvasWidth) {ctx.setFontSize(16);let lineWidth = 0;let lastSubStrIndex = 0; // 每次开始截取的字符串的索引const indentWidth = 20; // 定义缩进宽度let shouldIndent = false; // 是否需要缩进for (let i = 0; i < str.length; i++) {const charWidth = ctx.measureText(str[i]).width;lineWidth += charWidth;// 检查是否需要换行if (lineWidth > canvasWidth - indentWidth || str[i] === '。') {// 处理当前行文本let lineText = str.substring(lastSubStrIndex, i + 1);if (shouldIndent) {lineText = ' '.repeat(indentWidth / ctx.measureText(' ').width) + lineText;shouldIndent = false; // 只在句号后的一行缩进}ctx.fillText(lineText, leftWidth, initHeight); // 绘制文本initHeight += 22; // 16为字体的高度lineWidth = 0; // 新行开始时宽度为0lastSubStrIndex = i + 1; // 更新开始截取的索引// 如果遇到句号,设置需要缩进的标志if (str[i] === '。') {shouldIndent = true;}// 更新leftWidth并考虑缩进leftWidth = leftWidth;}}// 处理最后一行文本if (lastSubStrIndex < str.length) {let lineText = str.substring(lastSubStrIndex);if (shouldIndent) {lineText = ' '.repeat(indentWidth / ctx.measureText(' ').width) + lineText;}ctx.fillText(lineText, leftWidth, initHeight);}// 标题border-bottom 线距顶部距离titleHeight += 10;return titleHeight;
},

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

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

相关文章

C++(2)之Linux多线程服务端编程总结

C之Linux多线程服务端编程读书笔记 Author: Once Day Date: 2023年1月31日/2024年8月23日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章可参考专栏: Linux实践…

C++:类与对象

一、面向对象编程 (一) 面向过程vs面向对象 面向过程&#xff08;Procedural-Oriented-Programming&#xff0c; POP&#xff09;和面向对象&#xff08;Object-Oriented-Programming&#xff0c;OOP&#xff09;&#xff0c;是两种典型的编程范式&#xff0c;通常是作为划分编…

频带宽度固定,如何突破数据速率的瓶颈?

目录 目录 引言 信道 频带宽度 信噪比 信噪比的重要性 影响信噪比的因素 码元 码元的特点&#xff1a; 码元与比特的关系&#xff1a; 码元的作用&#xff1a; 码元的类型&#xff1a; Question 类比解释&#xff1a; 技术解释&#xff1a; 引言 在现代通信系统中…

OpenAI o1:AI领域的“草莓”革命,华人科学家贡献卓越

最近&#xff0c;科技界的热门明星“草莓”频繁出现在大家的视线中。9月11号&#xff0c;The Information报道称&#xff1a;OpenAI计划在未来两周内推出一款更智能、更昂贵、更谨慎的AI模型&#xff01;网友们对此消息持怀疑态度&#xff0c;认为类似消息屡见不鲜&#xff0c;…

centos8构建nginx1.27.1+BoringSSL+http3+lua+openresty

需要接入http3&#xff0c;索性最新的nginx在构建一波&#xff0c;趟一遍坑 准备工作 1.环境命令安装 yum install GeoIP -y yum install GeoIP-devel -y yum install libmaxminddb-devel -y yum install -y patch wget zlib zlib-devel lftp gcc gcc-c make openssl-devel p…

Pikachu靶场之csrf

CSRF 跨站请求伪造 CSRF入门及靶场实战 - FreeBuf网络安全行业门户 攻击者伪造恶意链接&#xff0c;诱使用户点击&#xff0c;这个链接附带了用户的认证凭据Cookie、Session等&#xff0c;执行操作如转账。 因为带了cookie、session&#xff0c;服务器认为是用户的行为。借用…

待机模式中WKUP上升沿模拟开机与关机

本篇博客重点在于标准库函数的理解与使用&#xff0c;搭建一个框架便于快速开发 目录 前言 待机模式 代码 wkup.h wkup.c main.c 使用注意 前言 建议先阅读下面的博客中待机模式部分。本博客主要分享代码-基于待机模式WKUP引脚的上升沿实现类似长按开机与关机的功能…

二维码的原理以及Java生成二维码【中间带图片】

一、什么是二维码&#xff1a; 二维码 &#xff08;2-dimensional bar code&#xff09;&#xff0c;是用某种特定的几何图形按一定规律在平面&#xff08;二维方向上&#xff09; 分布的黑白相间的图形记录数据符号信息的。 二、常用的码制 Data Matrix, Maxi Code, Aztec,…

看看智慧门诊银医通自助服务方案,如何化解医院患者跑难题

“看病三分钟&#xff0c;排队三小时”&#xff0c;这是许多患者在就医过程中的无奈吐槽。挂号队伍长如龙&#xff0c;看病流程繁琐复杂&#xff0c;缴费窗口人满为患&#xff0c;检查报告等待时间漫长…… 这些就医痛点&#xff0c;不仅让患者身心疲惫&#xff0c;也给医院的管…

基于微信小程序+Java+SSM+Vue+MySQL的宿舍管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于微信小程序JavaSSMVueMySQL的宿舍管理系统【附源码文档…

F1C100S/F1C200S的资料来源说明

文章目录 常用板子开源创客荔枝派榴莲派 我想说是的官网啥资料都没有。但是它的资料又很多&#xff0c;从淘宝或者其他地方能都搜到很多。 http://wiki.lcmaker.com/index.php?titleLC-PI-200S https://github.com/peng-zhihui/Planck-Pi?tabreadme-ov-file#head4 http://do…

使用 PyCharm 新建 Python 项目详解

使用 PyCharm 新建 Python 项目详解 文章目录 使用 PyCharm 新建 Python 项目详解一 新建 Python 项目二 配置环境1 项目存放目录2 Python Interpreter 选择3 创建隔离环境4 选择你的 Python 版本5 选择 Conda executable 三 New Window 打开项目四 目录结构五 程序编写运行六 …

虚拟机Linux+Ubuntu操作系统 如何在虚拟机上安装docker VMPro 2024在线激活资源

一般情况下 不建议在windows系统上安装docker Windows本身就自带一个虚拟机叫WSL 但是不推荐在日常使用的电脑上安装 我们要下一个虚拟机 我们在window上安装docker会被告知WSL内核太老 我们要一个专业的 隔离的虚拟机软件 推荐使用虚拟机 这是我们的虚拟机软件 我们这边…

深入链表的遍历——快慢指针算法(LeetCode——876题)

今天我们一起来学习一下一个快速遍历链表的方法 我们先来看看一道经典的需要遍历链表的题目 &#xff08;题目来自LeetCode&#xff09; 876. 链表的中间结点https://leetcode.cn/problems/middle-of-the-linked-list/ 给你单链表的头结点 head &#xff0c;请你找出并返回链…

网络安全 DVWA通关指南 DVWA Reflected Cross Site Scripting (反射型 XSS)

DVWA Reflected Cross Site Scripting (反射型 XSS) 文章目录 DVWA Reflected Cross Site Scripting (反射型 XSS)XSS跨站原理反射型 LowMediumHighImpossible 参考文献 WEB 安全靶场通关指南 XSS跨站原理 当应用程序发送给浏览器的页面中包含用户提交的数据&#xff0c;但没有…

鼎捷新一代PLM 荣膺维科杯 “2023年度行业优秀产品奖”

近日&#xff0c;由中国高科技行业门户OFweek维科网主办的“全数会2024&#xff08;第五届&#xff09;中国智能制造数字化转型大会暨维科杯工业自动化及数字化行业年度评选颁奖典礼”在深圳隆重举办。这不仅是中国工业自动化及数字化行业的一大品牌盛会&#xff0c;亦是高科技…

如何利用 CSS 渐变实现多样化背景效果

前言 总在平常看到像这样的图片 背景是如何实现的呢 背景效果的多样性和美观性直接影响用户体验。CSS 渐变为设计师提供了一种强大且灵活的方法来创建引人注目的背景。渐变是颜色之间平滑过渡的效果&#xff0c;通过调整渐变类型和设置&#xff0c;你可以轻松实现从简单到复杂…

DataWind将string类型转化为int类型的报错解决

一、现象&#xff1a; toInt64([kernel_wakeup_top_count_str]) 二、日志&#xff1a; 遇到&#xff1a;错误: 直连查询失败&#xff0c;内部异常:<class aeolus.aeolus.libs.exception.aeolus_base_exception.AeolusBaseException>: aeolus/logicQuery/logicQueryMysq…

【一分钟学C++】std::memory_order

竹杖芒鞋轻胜马,谁怕?一蓑烟雨任平生~ 公众号&#xff1a; C学习与探索 | 个人主页&#xff1a; rainInSunny | 个人专栏&#xff1a; Learn OpenGL In Qt 文章目录 写在前面为什么需要Memory OrderMemory OrderRelaxed OrderRelease-Acquire Order 写在前面 使用std::mem…

智慧交通基于yolov8的行人车辆检测计数系统python源码+onnx模型+精美GUI界面

【算法介绍】 智慧交通中&#xff0c;基于YOLOv8的行人车辆检测计数系统是一项高效、准确的技术解决方案。该系统利用YOLOv8这一先进的目标检测算法&#xff0c;结合深度学习技术&#xff0c;能够实时检测并准确计数道路上的行人和车辆。YOLOv8在保证检测速度的同时&#xff0…