uniapp使用canvas绘制卡片并下载到本地

该博客详细介绍了如何使用uniapp框架结合canvas组件,绘制包含图片、标题和简介的二维码,并最终将生成的图片保存到用户的相册。通过调整图片和文字的布局,确保内容始终以1.3:1的比例显示,同时对超出限制的简介进行省略号处理,实现美观且信息完整的二维码生成效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果:
在这里插入图片描述
简介最多显示3行,超过3行部分用省略号(…)代替。

代码:

<canvas style="width: 100%; height: 409px;" canvas-id="myCanvas"></canvas>
// 绘制图片
createImg (qrcode) {
	uni.showLoading({
		title: '生成中'
	})
	const that = this;
	const ctx = uni.createCanvasContext('myCanvas');
	
	uni.getImageInfo({
		src: 'http://www.test.com/demo.jpg', // 上半部分的图片地址
		success(info) {
			// 绘制图片, 原理:始终保持宽高比为1.3 : 1, 可以根据自己的情况调
			let draw_height = 225;

			if (info.height < info.width) {
				let width = info.width;
				ctx.drawImage(info.path, 0, 0, width, info.height, 0, 0, 293, draw_height);
			} else {
				let view_height = parseInt(info.width / 1.3); // 计算出可视区域的图片高度
				let height = info.height;
				if (info.height > draw_height) {
					height = parseInt((info.height - view_height) / 2); // 计算出图片绘制的y方向起点
				}
				ctx.drawImage(info.path, 0, height, info.width, view_height, 0, 0, 293, draw_height);
			}
			ctx.setFillStyle('#ffffff');
			ctx.fillRect(0, draw_height, 293, 150);

			// 绘制标题
			ctx.setFillStyle('#333333');
			ctx.setFontSize(13);
			//标题加粗
			ctx.fillText('标题', 19.5, 250);
			ctx.fillText('标题', 20, 249.5);

			// 绘制描述
			ctx.setFillStyle('#777777');
			
			// 绘制简介,超过3行用省略号(...)代替
			that.toFormateStr(ctx, that.circleDetail.content, 260, 3, 20, 275, 20);
			
			// 绘制底部矩形
			ctx.setFillStyle('#f5f5f5');
			ctx.fillRect(0, 338, 293, 71);
			
			// 绘制底部信息提示
			ctx.setFontSize(11.5);
			ctx.setFillStyle('#777777');
			ctx.fillText('达人SHOW-互动式社群新零售', 20, 368);
			ctx.fillText('扫码查看更多内容', 20, 392);
			
			// 绘制二维码
			ctx.setFillStyle('#ffffff');
			ctx.fillRect(220, 345, 56, 56);
			// qrcode:二维码url地址
			ctx.drawImage(qrcode, 224, 349, 48, 48); 
			ctx.draw(true);
			uni.hideLoading();
		}
	})
}


/**
*  	绘制换行文字
* 	@param	ctx: canvas绘图上下文
* 	@param	str: 需要绘制的文本内容
* 	@param	draw_width: 绘制的文字宽度
* 	@param	lineNum: 最多行数,比如最多显示(lineNum)3行,多出部分用'...'表示
* 	@param	startX: 绘制文字的起点 X 轴坐标
* 	@param	startY: 绘制文字的起点 Y 轴坐标
*	@param	steps: 每一行文字之间的间隔
* */ 
toFormateStr (ctx, str, draw_width, lineNum, startX, startY, steps ) {
	// 测量文本源尺寸信息(宽度)
	var strWidth = ctx.measureText(str).width;
	var startpoint = startY, keyStr = '', sreLN = strWidth / draw_width;
	// 计算文本源一共能生成多少行
	var liner = Math.ceil(sreLN);
	// 等比缩放,计算一行文本显示多少个字符
	let strlen = parseInt(str.length / sreLN);
				
	// 若文本不足一行,则直接绘制,反之大于传入的最多行数(lineNum)以省略号(...)代替
	if (strWidth  < draw_width) {
		ctx.fillText(str, startX, startpoint);
	} else {
		for (var i = 1; i < liner + 1; i++) {
			let startPoint = strlen * (i-1);
			if (i < lineNum || lineNum == -1) {
				keyStr = str.substr(startPoint, strlen);
				ctx.fillText(keyStr, startX, startpoint);
			} else {
				keyStr = str.substr(startPoint, strlen-5) + '...';
				ctx.fillText(keyStr, startX, startpoint);
				break;
			}
			startpoint = startpoint + steps;
		}
	}
}

保存到相册(canvas绘制的图):

saveImg () {
	uni.showLoading({
		title: '正在下载'
	})
	const baseW = 293, baseH = 409;
	uni.canvasToTempFilePath({
		x: 0,
		y: 0,
		width: baseW * 2,
		height: baseH * 2,
		destWidth: baseW * 2,
		destHeight: baseH * 2,
		quality: 1,
		canvasId: 'myCanvas',
		success: function(res) {
			// 在H5平台下,tempFilePath 为 base64
			uni.saveImageToPhotosAlbum({
				filePath: res.tempFilePath,
				success: function (data) {
					uni.hideLoading();
					uni.showToast({
						title: '已保存至相册!',
						icon: 'success',
						duration: 2000
					});
				}
			})
		} 
	})
}

很多方法都是直接用的uniapp官方API,盘就完了!

### UniApp Canvas 绘制图片下载UniApp 中,通过 `canvas` 绘制图片后实现下载功能涉及几个关键步骤。首先,确保能够正常绘制本地或网络图片canvas 上;其次,利用特定 API 将 canvas 转换成图片文件;最后,触发设备上的保存行为。 对于本地图片绘制,可直接调用 `ctx.drawImage()` 函数指定路径参数完成操作[^1]: ```javascript const ctx = uni.createCanvasContext('myCanvas'); // 本地图片绘制案例 ctx.drawImage('../../static/image/example.png', 0, 0, 100, 100); ctx.draw(); ``` 当处理来自服务器端返回的 URL 形式的网络图片时,则需先借助 `uni.getImageInfo` 获取资源信息再执行绘图动作[^2]: ```javascript uni.getImageInfo({ src: 'https://example.com/path/to/image.jpg', success(res) { const ctx = uni.createCanvasContext('myCanvas'); ctx.drawImage(res.path, 0, 0, 100, 100); ctx.draw(() => { // 完成后的回调逻辑... }); } }); ``` 为了支持用户点击按钮来下载绘制的内容作为图片文件,在页面布局中加入相应的控件,绑定事件处理器负责转换与存储过程。具体来说,可以通过 `wx.canvasToTempFilePath` 或者针对 H5 平台采用其他方式获取临时文件路径,进而调用系统的分享接口让用户选择保存位置[^4]: ```html <button @click="downloadImage">Download Image</button> <canvas id="myCanvas"></canvas> ``` ```javascript methods: { downloadImage() { let that = this; wx.canvasToTempFilePath({ x: 0, y: 0, width: 300, height: 300, destWidth: 900, destHeight: 900, canvasId: 'myCanvas', success(res) { console.log("Temporary file path:", res.tempFilePath); // 对于微信小程序环境下的保存提示 wx.saveImageToPhotosAlbum({ filePath: res.tempFilePath, success() { wx.showToast({ title: 'Saved successfully' }); }, fail(err) { console.error("Failed to save image", err); } }); // 如果是在H5环境下则可能需要创建a标签模拟点击下载链接的方式 if (process.env.VUE_APP_PLATFORM === 'h5') { var aLink = document.createElement('a'); aLink.href = res.tempFilePath; aLink.download = 'exported-image'; aLink.click(); } }, fail(err) { console.error("Error converting canvas to temp file", err); } },that.$scope || that); } } ``` 上述代码片段展示了如何在一个 Vue.js 驱动的应用程序上下文中定义一个名为 `downloadImage` 的方法,该方法会在用户按下按钮之后被激活,从而启动整个导出流程。注意这里的 `$scope` 是为了兼容某些版本的小程序开发框架而保留的一个属性访问尝试,实际项目里应根据具体情况调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值