uniapp将base64转化为图片,使用canvas绘制带图片和文字的海报并下载

<view class="shareConTuwen">
	<canvas canvas-id="posterCanvas" style="width:100%; height: 825rpx;"></canvas>
</view>
<view class="shareConBtn" @click="saveCanvasImg()">保存海报</view>
//其中太阳二维码是获取的base64格式,需要转化一下
// 获取小程序太阳二维码
GetWxaCodeunLimit() {
	var that = this
	uni.showLoading({
		title: '加载中...'
	})
	that.$http.sendRequest('url', 'POST', {
		access_token: that.access_token,
		scene: `sid=${this.shareItem.salemoduleid}&user=${uni.getStorageSync('userInfo').userId}`,
		page: 'pages/subPages/packageDetail',
		check_path: false,
		env_version: "",
		width: "",
		auto_color: "",
		is_hyaline: ""
	}).then(function(res) {
		uni.hideLoading()
		var bufferImg = res.data.result
		var imgData = bufferImg.replace(/[\r\n]/g, '') // 将回车换行换为空字符''
		const fs = wx.getFileSystemManager();
		//随机定义路径名称
		const times = new Date().getTime();
		const codeimg = wx.env.USER_DATA_PATH + '/' + times + '.jpeg';
		//将base64图片写入
		fs.writeFile({
			filePath: codeimg,
			data: imgData,
			encoding: 'base64',
			success: (res) => {
				//写入成功了的话,新的图片路径就能用了
				that.bufferImg = codeimg
			}
		});
	})
},
drawCanvas() {
	const ctx = uni.createCanvasContext('posterCanvas'); // 不需要传递 this
	// 获取屏幕宽度
	const sysInfo = uni.getSystemInfoSync();
	const canvasWidth = sysInfo.windowWidth * 0.8;//设置canvas宽度为屏幕宽度的80%
	// 设置背景颜色为白色
	ctx.setFillStyle('white');
	ctx.fillRect(0, 0, canvasWidth, 825); // 填充整个 canvas 区域
	ctx.drawImage(this.bufferImg, canvasWidth - 80, 320, 68, 68); // 太阳二维码图片
	// 昵称
	const nickname = this.userInfo.infoName;
	const nicknameFontSize = 12; // 昵称字体大小
	const nicknameFontColor = 'black'; // 昵称字体颜色
	// 这是昵称后面要跟随的文字
	const trailingText = '为您推荐';
	const trailingTextFontSize = 12; // 跟随文字的字体大小
	const trailingTextColor = 'gray'; // 跟随文字的字体颜色
	// 设置昵称的样式
	ctx.setFontSize(nicknameFontSize);
	ctx.setFillStyle(nicknameFontColor);
	// 绘制昵称
	ctx.fillText(nickname, 70, 337); // 假设昵称从左边10px处开始,垂直居中
	// 测量昵称的宽度
	const nicknameWidth = ctx.measureText(nickname).width;
	// 计算跟随文字的起始位置
	const trailingTextX = 70 + nicknameWidth + 10; // 昵称起始位置 + 昵称宽度 + 间距
	// 设置跟随文字的样式
	ctx.setFontSize(trailingTextFontSize);
	ctx.setFillStyle(trailingTextColor);
	// 绘制跟随文字
	ctx.fillText(trailingText, trailingTextX, 337);
	ctx.setFontSize(11);
	ctx.fillStyle = 'black';
	ctx.fillText(this.shareItem.salemodulename, 70, 365);
	ctx.setFontSize(11);
	ctx.fillStyle = '#969696';
	var xianshiPrice = '限时价:'
	ctx.fillText(xianshiPrice, 30, 401);
	// 绘制价格等(这部分也不依赖于图片加载)
	const orgprice = '¥' + this.shareItem.orgprice;
	ctx.setFontSize(22);
	ctx.fillStyle = '#FF0C01';
	ctx.fillText(orgprice, 72, 405);
	//获取限时价+现价的宽度
	var curpriceX = ctx.measureText(xianshiPrice).width + ctx.measureText(orgprice).width + 10 
	// 设置原价字体样式
	ctx.setFontSize(12);
	ctx.fillStyle = '#969696';
	const curprice = '¥' + this.shareItem.curprice;
	// 绘制文本
	ctx.fillText(curprice, curpriceX, 401);
	// 计算文本的宽度
	const textWidth = ctx.measureText(curprice).width;
	// 绘制删除线
	ctx.beginPath();
	ctx.setStrokeStyle = "#969696"; // 删除线颜色
	ctx.setLineWidth(0.5); // 删除线宽度
	ctx.moveTo(curpriceX, 396); // 从文本的中部开始绘制
	ctx.lineTo(curpriceX + textWidth, 396); // 绘制到文本的末尾
	ctx.stroke();
	// 设置套餐图片的尺寸和位置
	var imgWidth = canvasWidth; // 图片的宽度
	var imgHeight = 290; // 图片的高度
	var imgX = 0; // 图片在canvas上的x坐标
	var imgY = 0; // 图片在canvas上的y坐标
	var cornerRadius = 10; // 圆角的半径(以px为单位,如果你用rpx作为单位,需要转换为px)
	// 保存当前绘图状态
	ctx.save();
	ctx.beginPath();
	ctx.moveTo(imgX + cornerRadius, imgY); // 左上角开始
	ctx.arcTo(imgX + imgWidth, imgY, imgX + imgWidth, imgY + cornerRadius, cornerRadius); // 左上角圆角到右上角
	ctx.lineTo(imgX + imgWidth, imgY + imgHeight); // 右上角到右下角的直线
	ctx.lineTo(imgX, imgY + imgHeight); // 右下角到左下角的直线
	ctx.lineTo(imgX, imgY + cornerRadius); // 左下角到左上角的直线(不包含圆角部分)
	ctx.arc(imgX + cornerRadius, imgY + cornerRadius, cornerRadius, Math.PI, 1.5 * Math
	.PI); // 绘制左上角的圆角(完整圆的一部分)
	ctx.closePath();
	// 应用裁剪
	ctx.clip();
	// 绘制图片
	ctx.drawImage(this.product.imgUrl, imgX, imgY, imgWidth, imgHeight);
	// 恢复之前保存的绘图状态
	ctx.restore()
	// 加载并绘制圆形头像图片
	const imageWidth = 50;
	const imageHeight = 50;
	const borderRadius = imageWidth / 2;
	const centerX = 10 + imageWidth / 2; // 圆心 x 坐标
	const centerY = 305 + imageHeight / 2; // 圆心 y 坐标
	uni.getImageInfo({
		src: this.userInfo.imgUrl,
		success: (res) => {
			// 设置圆形剪切路径
			ctx.beginPath();
			ctx.arc(centerX, centerY, borderRadius, 0, 2 * Math.PI);
			ctx.closePath(); // 关闭路径
			ctx.clip(); // 应用剪切

			// 在剪切路径内绘制图片,确保图片的中心与圆心重合
			ctx.drawImage(res.path, centerX - imageWidth / 2, centerY - imageHeight / 2,
				imageWidth, imageHeight);

			// 所有内容都绘制完毕,现在绘制整个canvas
			ctx.draw(false, () => {
				console.log('整个 canvas 绘制完成');
			});
		},
		fail: (err) => {
			console.error('获取图片信息失败', err);
			// 处理图片加载失败的情况
		}
	});
},
//获取this.shareItem.imgurl的信息并调获取canvas信息
createPoster() {
	// 获取canvas上下文(drawCanvas方法中尽量不要多写uni.getImageInfo,以免图片不出现)
	uni.getImageInfo({
		src: this.shareItem.imgurl,
		success: (res) => {
			this.product.imgUrl = res.path;
			this.drawCanvas();
		},
		fail: (err) => {
			console.log(err);
		}
	});
},
//点击生成海报按钮
shareConNavEvt(index) {
	this.shareNavIndex = index
	if (index == 1) {
		this.createPoster()
	}
},
//保存海报
saveCanvasImg() {
	uni.canvasToTempFilePath({
		canvasId: 'posterCanvas',
		success: (res) => {
			// 生成海报图片的临时文件路径
			console.log(res.tempFilePath);
			uni.saveImageToPhotosAlbum({
				filePath: res.tempFilePath,
				success: () => {
					uni.showToast({
						title: '保存成功',
						icon: 'success',
					})
				},
				fail: (err) => {
					console.error('保存海报失败:', err);
				}
			});
		},
		fail: (err) => {
			console.error('生成海报时发生错误:', err);
		}
	});
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值