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

Posted 菜鸡爱上编程

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用canvas绘制微信小程序海报页面并保存相册-适用微信原生相关的知识,希望对你有一定的参考价值。

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

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把直接生成图片,然后在页面上直接显示生成好的图片。
如有问题,欢迎指正修改。

微信小程序 canvas绘制多行文本(文本换行)

参考技术A

有什么问题尽管留言~

由于我平时主要使用wepy开发项目 所以这些常用封装及项目架子都是使用的wepy
覆盖了一些常用操作与封装、登录流程、保存图片至相册及相关授权流程

以上是关于用canvas绘制微信小程序海报页面并保存相册-适用微信原生的主要内容,如果未能解决你的问题,请参考以下文章

利用微信小程序中Canvas API来合成海报生成组件封装

利用微信小程序中Canvas API来合成海报生成组件封装

微信小程序 canvas绘制多行文本(文本换行)

微信小程序导出当前画布指定区域的内容并生成图片保存到本地相册(canvas)

canvas微信小程序如何导入个人微信

小程序生成海报保存图片到相册小测试