微信小程序-生成canvas图片并保存到手机相册
wxml页面
<button class="rightbtn bottomBtnCss" catch:tap="canvasImg"><image src='{{imgUrl}}/images/mine/jspj-icon.png' class="restNumImg"></image><text class="btnText">生成图片</text></button>
<!-- 生成图片弹框 -->
<view class="wx-dialog_wrapper " wx:if="{{isShowCanvas}}" ><view class="wx-dialog wx-dialogwidth80"><view class="wx-dialog_body"><view class="canvasWrap"><canvas type="2d" id='posterCanvas' style="width: 100%;height: 1000rpx;"></canvas></view><button class="rightbtn bottomBtnCss" catch:tap="saveImg"><image src='{{imgUrl}}/images/mine/jspj-icon.png' class="restNumImg"></image><text class="btnText">保存图片</text></button></view></view>
</view>
wxss页面
.wx-dialogwidth80{width:80%;
}
#posterCanvas {margin: 0 auto;
}
.canvasWrap {
margin: 10px auto;
text-align: center;
}
js代码
const app = getApp()
Page({/*** 页面的初始数据*/data: {imgUrl: app.globalData.imgUrl,//线上图片路径totalCnt: '',isSaveCanvas: false,},/*** 生命周期函数--监听页面加载*/onLoad(options) {let totalCnt = wx.getStorageSync('totalCnt')this.setData({totalCnt: totalCnt || '0.00'})},// 重新计算restClick() {wx.navigateTo({url: '../../index'})},/*** 用户点击右上角分享*/onShareAppMessage() {},// 关闭showVipDialogClose() {this.setData({isShowCanvas: false})},canvasImg() {this.setData({isShowCanvas: true})// wx.showLoading({// title: '海报生成中...',// })let _this = this//选取画板const query = wx.createSelectorQuery()query.select('#posterCanvas').fields({node: true,size: true}).exec(async (res) => {const canvas = res[0].node;const ctx = canvas.getContext('2d');const dpr = wx.getSystemInfoSync().pixelRatio //手机分辨率 为了使保存到相册的图片清晰canvas.width = res[0].width * dprcanvas.height = res[0].height * dprconsole.log('dpr', dpr);ctx.clearRect(0, 0, 320, 410); //清空画板ctx.fillStyle = '#fff';ctx.fillRect(0, 0, 320, 410);// 1.背景图const image = canvas.createImage();image.src = this.data.imgUrl + "/images/carbonEmissionImages/排放总量背景.png";;let bgImg = await new Promise((resolve, reject) => {image.onload = () => {resolve(image)}image.onerror = (e) => {reject(e)}});ctx.drawImage(bgImg, 0, 0, canvas.width, canvas.height);// 2.头部文字 在背景图上作画// 设置文字样式ctx.font = "700 36px sans-serif";ctx.fillStyle = "#fff";ctx.textAlign = "center" //居中是以文字设定的x轴( canvas.width/2)为中心点// 添加文字ctx.fillText("我在ESGPRO上测了企业碳排放总量", canvas.width / 2, 200);// 3.画中心圆图const image1 = canvas.createImage();image1.src = this.data.imgUrl + "/images/carbonEmissionImages/tco2背景.png";;let bgImgPo = await new Promise((resolve, reject) => {image1.onload = () => {resolve(image1)}image1.onerror = (e) => {reject(e)}});ctx.drawImage(bgImgPo, 0.5 * (canvas.width - 400), 0.5 * (canvas.height - 800), 400, 400);// 4.圆圈内文字 在背景图上作画// // 设置文字样式ctx.font = "700 36px sans-serif";ctx.fillStyle = '#00bf5b'; //文字颜色:默认黑色ctx.textAlign = "center"ctx.fillText(_this.data.totalCnt, canvas.width / 2, 0.5 * (canvas.height - 400)) //绘制文本// 设置文字样式ctx.font = "28px sans-serif";ctx.fillStyle = "#bdbdbd";ctx.textAlign = "center" //居中是以文字设定的x轴( canvas.width/2)为中心点// 添加文字ctx.fillText('tCO2', canvas.width / 2, 0.5 * (canvas.height - 300));// 5.小程序二维码let image2 = canvas.createImage();// image2.src = this.data.imgUrl + '/images/carbonEmissionImages/COimg.jpg'; // 引入本地图片image2.src = '../../images/COimg.jpg'; // 引入本地图片image2.onload = function () {ctx.drawImage(image2, 0.5 * (canvas.width - 300), 0.5 * (canvas.height + 400), 300, 300);// 6.添加文字// 设置文字样式ctx.font = "24px sans-serif";ctx.fillStyle = "#999999";ctx.textAlign = "center" //居中是以文字设定的x轴( canvas.width/2)为中心点// 添加文字ctx.fillText('微信扫码或搜索ESGPRO', canvas.width / 2, 0.5 * (canvas.height + 1100));ctx.font = "24px sans-serif";ctx.fillStyle = "#999999";ctx.textAlign = "center" //居中是以文字设定的x轴( canvas.width/2)为中心点// 添加文字ctx.fillText('即可免费使用碳排放计算器', canvas.width / 2, 0.5 * (canvas.height + 1200));}})},async saveImg() {let _this = this;const query = wx.createSelectorQuery();const canvasObj = await new Promise((resolve, reject) => {query.select('#posterCanvas').fields({node: true,size: true}).exec(async (res) => {resolve(res[0].node);})});wx.canvasToTempFilePath({canvas: canvasObj, //现在的写法success: (res) => {console.log(res);_this.setData({isShowCanvas: false});//保存图片wx.saveImageToPhotosAlbum({filePath: res.tempFilePath,success(res) {wx.hideToast();wx.showModal({title: '图片保存成功',content: '图片成功保存到相册了',showCancel: false,confirmText: '好哒',confirmColor: '#5096cd',success: function (res) {if (res.confirm) {console.log('用户点击确定');}}})},fail(err) {wx.hideToast()if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" ||err.errMsg === "saveImageToPhotosAlbum:fail auth deny" ||err.errMsg === "saveImageToPhotosAlbum:fail authorize no response") {wx.showModal({title: '提示',content: '需要您授权保存相册',showCancel: false,success: res => {wx.openSetting({success(res) {if (settingdata.authSetting['scope.writePhotosAlbum']) {wx.showModal({title: '提示',content: '获取权限成功,再次点击即可保存',showCancel: false,})} else {wx.showModal({title: '提示',content: '获取权限失败,将无法保存到相册哦~',showCancel: false,})}},fail(err) {console.log("fail", err)},complete(res) {console.log("finish", res)}})}})} else if (err.errMsg === "saveImageToPhotosAlbum:fail cancel") {wx.showModal({title: '提示',content: '取消了保存图片,再次点击下载即可保存',showCancel: false,})} else {wx.showModal({title: '提示',content: err.errMsg,showCancel: false,})}}})},fail(err) {wx.showToast({title: '保存失败,稍后再试',duration: 2000,icon: 'none'});}}, this)},/*** 生命周期函数--监听页面初次渲染完成*/onReady() {},/*** 生命周期函数--监听页面显示*/onShow() {},/*** 生命周期函数--监听页面隐藏*/onHide() {},/*** 生命周期函数--监听页面卸载*/onUnload() {},/*** 页面相关事件处理函数--监听用户下拉动作*/onPullDownRefresh() {},/*** 页面上拉触底事件的处理函数*/onReachBottom() {},})
相关文章:
微信小程序-生成canvas图片并保存到手机相册
wxml页面 <button class"rightbtn bottomBtnCss" catch:tap"canvasImg"><image src{{imgUrl}}/images/mine/jspj-icon.png class"restNumImg"></image><text class"btnText">生成图片</text></but…...
设计模式8:代理模式-动态代理
上一篇:设计模式8:代理模式-静态代理 目录 如何理解“动态”这两个字?动态代理简单的代码实例一个InvocationHandler代理多个接口有动态代理,为什么还要用Cglib代理? 如何理解“动态”这两个字? “动态”…...
tcp字节传输(java)-自定义包头和数据识别
1、背景 tcp传输的时候会自动拆包,因此服务端接收的数据段可能跟客户端发送过来的数据段长度不一致,比如客户端一次发送10000个字节。但是服务端接收了两次才接收完整(例如第一次接收6000字节,第二次接收4000字节)。但…...
pyspark 系统找不到指定的路径; \Java\jdk1.8.0_172\bin\java
使用用具PyCharm 2023.2.1 1:pyspark 系统找不到指定的路径, Java not found and JAVA_HOME environment variable is not set. Install Java and set JAVA_HOME to point to the Java installation directory. 解决方法:配置正确环境变量…...
UE4 Physics Constraint Actor 实现钟摆效果
放入场景,然后将一个球体放入场景 选择小球 将小球改为Movable 选择模拟物理,并将小球移除平衡点 就实现了...
UE4/UE5 动画控制
工程下载 https://mbd.pub/o/bread/ZJ2cm5pu 蓝图控制sequence播放/倒播动画: 设置开启鼠标指针,开启鼠标事件 在场景中进行过场动画制作 设置控制事件...
Springboot整合shiro
导入依赖 <!-- 引入springboot的web项目的依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency> <!-- shiro --><depende…...
阻塞/非阻塞、同步/异步(网络IO)
1.阻塞/非阻塞、同步/异步(网络IO) 【思考】典型的一次 IO 的两个阶段是什么? 数据就绪 和 数据读写 数据就绪 :根据系统 IO 操作的就绪状态 阻塞 非阻塞 数据读写 :根据应用程序和内核的交互方式 同步 异步 陈硕:在处理 IO …...
为什么大家会觉得考PMP没用?
一是在于PMP这套知识体系,是一套底层的项目管理逻辑框架,整体是比较抽象的。大家在学习工作之后,会有人告诉你很多职场的一些做事的规则,比如说对于沟通,有人就会告诉如何跟客户沟通跟同事相处等等,这其实就…...
AVR128单片机 USART通信控制发光二极管显示
一、系统方案 二、硬件设计 原理图如下: 三、单片机软件设计 1、首先是系统初始化 void port_init(void) { PORTA 0xFF; DDRA 0x00;//输入 PORTB 0xFF;//低电平 DDRB 0x00;//输入 PORTC 0xFF;//低电平 DDRC 0xFF;//输出 PORTE 0xFF; DDRE 0xfE;//输出 PO…...
为什么5G 要分离 CU 和DU?(4G分离RRU 和BBU)
在 Blog 一文中,5G--BBU RRU 如何演化到 CU DU?_5g rru_qq_38480311的博客-CSDN博客 解释了4G的RRU BBU 以及 5G CU DU AAU,主要是讲了它们分别是什么。但是没有讲清楚 为什么,此篇主要回答why。 4G 为什么分离基站为 RRU 和 BBU…...
Python中的数据输入
获取键盘输入 input语句 使用input()可以从键盘获取输入,使用一个变量来接收 print("你是谁?") name input() print(f"我知道了,你是{name}")# print("你是谁?") name input("你是谁&…...
cms系统稳定性压力测试出现TPS抖动和毛刺的性能bug【杭州多测师_王sir】
一、并发线程数100,分10个阶梯,60秒加载时间,运行1小时进行压测,到10分钟就出现如下 二、通过jstat -gcutil 16689 1000进行监控...
【UE】材质描边、外发光、轮廓线
原教学视频链接: ue4 材质描边、外发光、轮廓线_哔哩哔哩_bilibili 步骤 1. 首先新建一个材质,这里命名为“Mat_outLine” 在此基础上创建一个材质实例 2. 在视口中添加一个后期处理体积 设置后期处理体积为无限范围 点击添加一个数组 选择“资产引用”…...
百模大战,打响AI应用生态的新赛点
点击关注 文|郝鑫 黄小艺,编|刘雨琦 “宇宙中心”五道口,又泛起了昔日的光芒。 十字路口一角的华清嘉园里,各种互联网大佬们,王兴、程一笑、张一鸣等人的创业传说似乎还有余音,后脚搬进来的AI…...
【C++二叉树】进阶OJ题
【C二叉树】进阶OJ题 目录 【C二叉树】进阶OJ题1.二叉树的层序遍历II示例代码解题思路 2.二叉搜索树与双向链表示例代码解题思路 3.从前序与中序遍历序列构造二叉树示例代码解题思路 4.从中序与后序遍历序列构造二叉树示例代码解题思路 5.二叉树的前序遍历(非递归迭…...
C++——vector:resize与reserve的区别,验证写入4GB大数据时相比原生操作的效率提升
resize和reserve的区别 reserve:预留空间,但不实例化元素对象。所以在没有添加新的对象之前,不能引用容器内的元素。而要通过调用push_back或者insert。 resize:改变容器元素的数量,且会实例化对象(指定或…...
基础配置xml
# 配置端口 server.port8081# 文件上传配置 # 是否支持文件上传 spring.servlet.multipart.enabledtrue # 是否支持文件写入磁盘 spring.servlet.multipart.file-size-threshold0 # 上传文件的临时目录 spring.servlet.multipart.locationd:/opt/tmp # 最大支持上传文件大小 sp…...
win环境安装SuperMap iserver和配置许可
SuperMap iServer是我国北京超图公司研发的基于跨平台GIS内核的云GIS应用服务器产品,通过服务的方式,面向网络客户端提供与专业GIS桌面产品相同功能的GIS服务,能够管理、发布多源服务,包括REST服务、OGC服务等。 SuperMap iserve…...
【Apollo学习笔记】——规划模块TASK之PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER(一)
文章目录 TASK系列解析文章前言PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER功能介绍PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER相关配置PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER流程确定优化变量定义目标函数定义约束ProcessSetUpStatesAndBoundsOptimizeByQPCheckSpeedLimitF…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
