用canvas绘制微信小程序海报页面并保存相册-适用微信原生

2023-11-08

微信小程序绘制海报并保存相册

tip:代码中使用的是uni的api 如果使用原生微信小程序开发,可以把uni更换成wx使用


前言

本片文章主要是把我工作中实际用到,可以整合出来的功能,做一个总结和讲解。

1、如何使用canvas
2、canvas绘制后如何生成图片
3、将图片保存到相册
4、难点:如何解决canvas层级高于position定位层级问题,如何适配不同屏幕大小比例


一、分析需求

两种方案:

  1. 进入页面先绘制canvas,点击按钮后再生成图片并保存相册
  2. 进入页面先绘制canvas,并生成图片,点击按钮直接保存图片到相册

我这边使用的是第一种方式,看实际需求。(其实没多大区别)

二、准备数据

在开始绘制canvas之前首先要,分析页面中用到了哪些内容:

  1. 背景图片
  2. 二维码图片
  3. 关于海报的一些描述性文案

注意:
1、由于这些数据可能不是页面写死的内容,是根据api返回的数据,所以需要在绘制canvas之前就先准备好从api返回的数据。
2、需要考虑同步问题


三、编码开始

先看下页面图片样式
效果图

html部分

<canvas :style="{height:pageHeight,width: _width +'px'}" canvas-id="mycanvas" />
<cover-view @tap="saveImg">
	<cover-image src="btn_img.png"></cover-image>
</cover-view>

解析:

1、首先需要准备一个canvas用于绘制页面内容的载体,id是唯一标识
2、需要一个按钮用于保存图片,但是发现即使用绝对定位调整层级还是不能将按钮显示到canvas上层,所以借助于官方提供的覆盖原生组件的方法。cover-viewcover-image

js部分

这里只说代码重点部分。

页面中用到的变量可以自行修改,至于变量的初始值都可以是空字符串

1、准备好数据后开始绘制

onReady() {
	// 为了兼容不同机型页面大小,所以需要先获取到页面宽高
	this.getSysInfo()
},
getSysInfo() {
	/*获取手机宽高*/
	let that = this
	let imgUrl = this.imageUrl
	let qrcodeUrl = this.codeUrl
	uni.getSystemInfo({
		success(res) {
			console.log('屏幕宽度', res)
			that._width = res.windowWidth
			that._heigth = res.windowHeight
			// 获取图片信息生成canvas
			// 因为这里用的网络图片所以需要先获取本地网络图地址
			that.getImginfo([imgUrl, qrcodeUrl], 0);
		}
	})
},
getImginfo(urlArr, _type) {
	let that = this;
	uni.getImageInfo({
		src: urlArr[_type],
		success: function(res) {
			//res.path是网络图片的本地地址
			if (_type === 0) { //
				that.localImageUrl = res.path
				that.getImginfo(urlArr, 1)
			} else {
				//二维码
				that.localCodeUrl = res.path
				// 创建canvas图片
				that.createNewImg();
			}
		},
		fail: function(res) {
			//失败回调
			console.log('错误', _type, res)
		}
	});
},
createNewImg() {
	let that = this;
	let ctx = uni.createCanvasContext('mycanvas');
	// 绘制背景
	ctx.drawImage(this.localImageUrl, 0, 0, this._width, this._heigth - 44 - this.statusBarHeight);
	// 绘制二维码区域
	ctx.lineJoin = "round";
	ctx.lineWidth = 12;
	ctx.setFillStyle('#FFFFFF')
	ctx.setStrokeStyle('#FFFFFF')

	// 二维码区域y坐标
	const yPosition = this._heigth - 44 - this.statusBarHeight - this.remSize(98) - 100
	ctx.strokeRect(this.remSize(24), yPosition, this.remSize(326), this.remSize(98));
	ctx.fillRect(this.remSize(24), yPosition, this.remSize(326), this.remSize(98));

	// 绘制二维码
	const yPosition2 = yPosition + 4
	ctx.drawImage(this.localCodeUrl, this.remSize(28), yPosition2, this.remSize(90), this.remSize(90));

	//二维码区域文字
	let title1 = this.tips.title1;
	let title2 = this.tips.title2;
	let title3 = this.tips.title3;
	// 文字一
	ctx.setFontSize(this.remSize(14));
	ctx.setFillStyle('#333333');
	ctx.fillText(title1, this.remSize(128), yPosition + this.remSize(30));
	// 文字二三
	ctx.setFillStyle('#B8B8B8');
	ctx.setFontSize(this.remSize(12));
	ctx.fillText(title2, this.remSize(128), yPosition + this.remSize(62));
	ctx.fillText(title3, this.remSize(128), yPosition + this.remSize(85));
	// 绘制
	ctx.draw();

	//将生成好的图片保存到本地
	uni.canvasToTempFilePath({
		canvasId: 'mycanvas',
		success: (res)=> {
			that.loadImagePath = res.tempFilePath
		},
		fail: (res)=> {
			console.log(res);
		}
	});
},
// 缩放比例
let scalePage = uni.getSystemInfoSync().windowWidth / 375

remSize(num) {
	return num * scalePage
},

解释:

1、uni.createCanvasContext创建canvas上下文,用于操作绘制具体图片和文字
2、ctx.drawImage用于绘制图片
3、ctx.setFillStyle用于绘制填充色
4、ctx.setStrokeStyle用于绘制边框颜色
5、因为canvas不能绘制圆角实心矩形,所以取巧的方式,就是用圆角矩形和实心矩形覆盖的方式,效果见上图。
6、ctx.strokeRect绘制矩形空心
7、ctx.fillRect绘制矩形实心
6、ctx.setFontSize ctx.setFillStyle ctx.fillText 绘制文字大小,颜色,位置
7、ctx.draw() 把所有的上下文内容,绘制到canvas上面
特别说明:

  1. remSize方法,根据设计稿去设置图片大小和文案的位置比例,我这边是根据375像素的宽度计算比例。
  2. 这些api具体使用方法,可以参考官方文档,这里就不一一列举了。

2、保存图片

//点击保存到相册
saveImg() {
	uni.saveImageToPhotosAlbum({
		filePath: this.loadImagePath,
		success(res) {
			uni.showToast({
				title: '已保存到相册',
				icon: 'success',
				duration: 3000
			})
		}
	})
},

解析:

1、因为保存按钮是固定定位,并且按钮并非canvas绘制内容,所以保存图片的时候并不会有按钮。
2、需要注意的是,保存相册是需要相册保存权限的,这个可以看文档自己去设置。

总结

上面的说的覆盖问题,还可以是先使用canvas把直接生成图片,然后在页面上直接显示生成好的图片。
如有问题,欢迎指正修改。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用canvas绘制微信小程序海报页面并保存相册-适用微信原生 的相关文章

  • C++11:右值引用

    新特性目的 右值引用 Rvalue Referene 是 C 新标准 C 11 11 代表 2011 年 中引入的新特性 它实现了转移语义 Move Sementics 和精确传递 Perfect Forwarding 它的主要目的有两个方
  • 【论文阅读】Three scenarios for continual learning

    文章目录 题目 2019 Three scenarios for continual learning 1 论文的总体介绍 2 论文提出的 benchmark 三种场景 2 1 三种场景的定义如下 2 2 split task protoc
  • 动态个人导航网HTML单页源码

    一款单页的网址发布页单页 HTML 模板 可用于网址发布页使用 本模板简约商务 页面精美没有花里胡哨的效果 喜欢的敬请使用 右键单击直接就可以单页面修改 直接下载就可以使用啦 源码地址 旭音导航网 zip 蓝奏云
  • unix域套接字

    UNIX域套接字被用来和同一机器上运行的进程通信 尽管因特网域套接字可以用作同样的目的 然而UNIX域套接字更高效 UNIX域套接字只拷贝 数据 它们没有要执行的协议处理 没有要增加或删除的网络头 没有要计算的校验和 没有要产生的序列号 没

随机推荐

  • 量子芯片是什么

    量子芯片是一种制造的芯片 它能够用来执行量子计算任务 量子芯片通常是用来执行量子纠缠运算的 这是一种特殊的量子运算 可以用来解决计算机难以解决的问题 如密码破解 分子模拟和机器学习 量子芯片通常由多个量子比特 或称为量子位 组成 并且可以通
  • elementui 解决select框有值,但不回显问题

    问题描述 在使用Vue框架和element ui开发时 下拉框遇见一个问题 比如有一个所在地需要选择省市区 当省市选完后 选择区的时候 会发现值已经改变 但是区的下拉框没回显选中的数据 在打印中查看是修改成功了 但在页面中没有及时刷新改变后
  • 崩溃场景_【3D】MaxScript 回调脚本异常(病毒清理)撤销崩溃 灯光消失等常见问题...

    这是另众多3DMAX新老玩家头疼的问题 回调脚本异常是什么 其实它是病毒的体现 而且老版本的ALC等杀毒插件对它无效 出现这个弹窗伴随出现的就是撤销崩溃 灯光删除 关闭文件自动保存等等问题 来了解一下彻底解决的方法 视频版 图文版 1 打开
  • 记录一下 CMU 15445 项目

    目录 Write In Front PROJECT 1 BUFFER POOL TASK 1 LRU REPLACEMENT POLICY 核心概念 数据结构 Other TASK 2 BUFFER POOL MANAGER INSTANC
  • 区块链学习笔记3——BTC协议

    区块链学习笔记3 BTC协议 学习视频 北京大学肖臻老师 区块链技术与应用 笔记参考 北京大学肖臻老师 区块链技术与应用 公开课系列笔记 目录导航页 数字货币所面临的主要挑战 Double spending attack 双花攻击 同一张数
  • java es score_elasticsearch java原生打分插件开发

    能有影响elasticsearch score的方法有很多 官方推荐的是使用内置的painless脚本语言结合function score来重新定义score 由于本人开发的项目其算法是由java语言开发的 于是决定尝试原生脚本开发 ela
  • 石油信息化新技术应用前景

    随着石油信息化集中集成 物联网的建设 云计算 移动互联 大数据技术在石油行业的应用前景如何呢 什么是智慧油田 智能油田呢 个人的一些想法总结如下 对行业的关注基本停留在14年4月 疏漏局限难免 一 关于云计算基础设施在互联网 电商领域应用方
  • html常见标签总结1

    1 常见标签总结01 代码 h1 文本修饰标签 h1 h2 表强调 h2 p strong 这是strong文本修饰标签的效果 strong p p em 这是em文本修饰标签的效果 em p p strong的强调效果更强 em的强调效果
  • linux,时间改成utc

    ln sf usr share zoneinfo UTC etc localtime 运行ok
  • 系统修复模式(Recovery mode) 的体验

    什么是修复模式 直观的体验就是在你的normal mode失败的时候 你发现在你的启动页面 和grub有关 有另一种选项就是recovery mode 具体的定义可以搜索百度或其他 为什么在其他启动失败的时候 修复模式能进入系统 我的经历是
  • Spring MVC静态资源处理

    优雅REST风格的资源URL不希望带 html 或 do 等后缀 由于早期的Spring MVC不能很好地处理静态资源 所以在web xml中配置DispatcherServlet的请求映射 往往使用 do xhtml等方式 这就决定了请求
  • 2023年十大最佳自动化测试工具

    Best Automation Testing Tools for 2023 对更快交付高质量软件 或 快速质量 的需求要求组织以敏捷 持续集成 CI 和DevOps方法论来寻找解决方案 测试自动化是这些方面的重要组成部分 最新的 2018
  • 合并DataGrid单元格

    做项目有时也会遇到要合并DataGrid单元格的情况 在DataGrid单元格中有ColumnSpan RowSpan Visible属性 这跟Table控件中的colspan rowspan属性相同 因此我们可以利用这些属性来合并Data
  • 前端例程20221012:宣纸材质背景

    演示 原理 使用 background image 加载材质图片 材质图片使用半透明的灰度图像 使用 background color 进行染色 代码
  • 在IDEA集成Github

    在IDEA集成Github 在IDEA中设置Git 在File gt Setting gt Version Control gt Git gt Path to Git executable选择你的git安装后的git exe文件 然后点击T
  • OC_YYModel字典转模型的几种详细用法

    OC YYModel字典转模型的几种详细用法 目录 JSON转字符串 普通字典转模型 模型属性有自定义的模型YYUSer 属性有数组 数组里自定义模型 还有字典和集合 字典里的key与模型里的属性名不一致 常用的几个方法 json转模型 i
  • 以太坊分片Sharding FAQ

    简介 目前 在所有的区块链协议中每个节点存储所有的状态 账户余额 合约代码和存储等等 并且处理所有的交易 这提供了大量的安全性 但极大的限制了可扩展性 区块链不能处理比一个单节点更多的交易 很大程度上因为这个原因 比特币被限制在每秒3 7笔
  • 【Linux篇】第八篇——Linux下的进程控制(进程创建+进程终止+进程等待+进程程序替换+简易shell的实现)

    这篇博客就要开始聊一聊进程控制相关的内容了 这部分的内容十分的丰富且十分的重要 学好这一块内容是非常有必要的 目录 进程创建 fork函数 写时拷贝 进程终止 进程退出的三种场景 进程常见的退出方法 进程等待 进程等待的方法 wait方法
  • Unity 实用小技巧合集

    Unity小技巧介绍 一 Unity小技巧介绍 二 Unity小技巧介绍 三 Unity小技巧介绍 四
  • 用canvas绘制微信小程序海报页面并保存相册-适用微信原生

    微信小程序绘制海报并保存相册 tip 代码中使用的是uni的api 如果使用原生微信小程序开发 可以把uni更换成wx使用 文章目录 微信小程序绘制海报并保存相册 前言 一 分析需求 二 准备数据 三 编码开始 html部分 解析 js部分