在uniapp中使用canvas制作海报(二)

项目场景:

提项目场景:在uniapp中制作分享海报,使用canvas制作并保存到本地,做了好久终于做完了!


解决方案:

第一步:制作页面:

<view class="popup">
			<uni-popup ref="popup" type="center" background-color="none">
				<view class="hb" ref="imageTest" id="imageTest">
					<view class="hb-bg" ref="bgImage" id="bgImage">
						<u-image width="300px" :src="backgroundPath" mode="widthFix"></u-image>
					</view>
					<view class="hb-content">
						<view class="hb-content-box">
							<u-avatar size="100" :src="avatarPath" id="imageAvatar"></u-avatar>
							<view class="hb-box-text">
								<view class="hb-name">{{agentName}}</view>
								<view class="hb-text">
									邀请您参加活动
								</view>
							</view>
						</view>

						<view class="hb-code">
							<u-image width="50px" :src="qrcodePath" mode="widthFix"></u-image>
						</view>
					</view>
				</view>

				<u-button plain type="info" @click="setCanvas" :custom-style="customStyle" style="  
					width: 85%;
					">
					保存图片
				</u-button>

			</uni-popup>
			<u-popup v-model="show" mode="center">

				<canvas id='canvas' class='canvas' canvas-id="firstCanvas" :style="'width: '+canvasWidth+'px; height: '+canvasHeight+'px;'"></canvas>

			</u-popup>
		</view>

第二步:将所有的图片转换为临时文件
 

// 生成二维码临时文件
			getNetworkImage(option) {
				// var projectId = option.projectId
				// if (projectId && projectId != undefined && projectId != "undefined" && projectId != null && projectId !=
				// 	"null") {
				// 	option.projectId = projectId
				// } else {
				// 	option.projectId = ""
				// }

				// var projectDId = option.projectDId
				// if (projectDId && projectDId != undefined && projectDId != "undefined" && projectDId != null &&
				// 	projectDId != "null") {
				// 	option.projectDId = projectDId
				// } else {
				// 	option.projectDId = ""
				// }

				// var agentId = option.agentId
				// if (agentId && agentId != undefined && agentId != "undefined" && agentId != null && agentId != "null") {
				// 	option.agentId = agentId
				// } else {
				// 	option.agentId = ""
				// }
				// console.log("===getShareCode===")
				// console.log("projectId:", option.projectId, ";projectDId:", option.projectDId, ';agentId:', option.agentId)
				return new Promise((resolve, reject) => {
					// console.log("分享二维码链接:", process.env.VUE_APP_URL +
					// 	"/ins/app/share/project/project/getShareCode?projectId=" + option.projectId +
					// 	"&projectDId=" + option.projectDId + "&agentId=" + option.agentId + "&shareWay=" + "3")
					uni.downloadFile({
						url: "http://img1.gtimg.com/sh/pics/hv1/209/239/1533/99744479.jpg",
						success: (e) => {
							const p = e.tempFilePath
							if (p.indexOf('json') > -1) {
								uni.showToast({
									title: '二维码生成失败,花花加急处理中,请优先使用一键分享!',
									icon: "none",
									duration: 3000
								})
								this.disabled = true
								console.log("disabled", this.disabled)
								reject(p)
								return false
							}
							this.qrcodePath = p
							resolve(p)
						},
						fail: (r) => {
							uni.showToast({
								title: '二维码生成失败,花花加急处理中,请优先使用一键分享!',
								icon: "none",
								duration: 3000
							})
							this.disabled = true
							reject(r)
						}
					})
				})
			},


			//生成海报背景图临时文件
			async getBackgroundImage() {
				this.backgroundPath = await this.imageDownloadFile(
					'http://5b0988e595225.cdn.sohucs.com/images/20190725/9af6a5c7aaad426a8926f7bd4a93f41a.jpeg')
			},

			//生产头像临时文件
			async getAvatarImage() {
				this.avatarPath = await this.imageDownloadFile(
					'http://img.touxiangwu.com/2020/3/uq6Bja.jpg')
			},

			//图片临时文件
			imageDownloadFile(image) {
				return new Promise((resolve, reject) => {

					uni.downloadFile({
						url: image,
						success: (e) => {
							const p = e.tempFilePath
							if (p.indexOf('json') > -1) {
								uni.showToast({
									title: '二维码生成失败,花花加急处理中,请优先使用一键分享!',
									icon: "none",
									duration: 3000
								})
								this.disabled = true
								console.log("disabled", this.disabled)
								reject(p)
								return false
							}

							resolve(p)
						},
						fail: (r) => {
							uni.showToast({
								title: '二维码生成失败,花花加急处理中,请优先使用一键分享!',
								icon: "none",
								duration: 3000
							})
							this.disabled = true
							reject(r)
						}
					})
				})
			},

第三步:使用canvas绘制,并且保存到本地,
 

// 保存海报
			setCanvas() {

				// console.log("qrcodePath",this.qrcodePath)
				// this.$refs.popup.open('center')
				this.show = true
				setTimeout(() => {
					this.drawPoster()
				}, 1000)
			},
			drawPoster() {
				var that = this
				const ctx = uni.createCanvasContext('firstCanvas', this)
				var drawImageBackground = that.backgroundPath
				var drawAvatarImage = that.avatarPath
				var drawImageqrcodePath = this.qrcodePath
				// 获取海报背景宽/高
				uni.createSelectorQuery().in(this).select('#imageTest').boundingClientRect(function(
					rect) { //查询节点信息的对象 返回一个对象
					let canvasWidth = that.canvasWidth = rect.width;
					let canvasHeight = that.canvasHeight = rect.height;
					ctx.clearRect(0, 0, canvasWidth, canvasHeight) // 清除画布
					ctx.beginPath(); //开始创建一个路径
					ctx.rect(0, 0, canvasWidth, canvasHeight);
					ctx.setFillStyle("#FFFFFF") // 背景色
					ctx.stroke();
					ctx.fill(); //填充
					return rect
				}).exec();

				// 获取海报大图
				uni.createSelectorQuery().in(this).select('#bgImage').boundingClientRect(function(rect) {
					console.log("海报大图:", rect)
					ctx.beginPath()
					//绘制图片
					ctx.drawImage(drawImageBackground, 0, 0, rect.width, rect.height - 5); //图片
					ctx.fill();
					ctx.save()
					console.log("rect.height", rect.height)
					ctx.arc(38, rect.height + 30, 28, 0, 2 * Math.PI) //画一条弧线。创建一个圆
					ctx.clip() //从原始画布中剪切任意形状和尺寸。

				}).exec()

				uni.createSelectorQuery().in(this).select('#bgImage').boundingClientRect(function(rect) {
					console.log("头像高度和宽度:", rect)
					// 绘制头像
					ctx.beginPath()
					console.log("drawAvatarImage", drawAvatarImage)
					ctx.drawImage(drawAvatarImage, 10, rect.height, 56, 56); //绘制图片
					ctx.restore() //任意时间对其进行恢复
					ctx.fill();

					//绘制文字
					ctx.beginPath()
					ctx.setFillStyle('#000000'); //文本颜色
					ctx.setTextAlign('left') //对齐方式
					ctx.setFontSize(15) //字号
					ctx.fillText(that.agentName, 80, rect.height + 25) //文本内容及文本位置

					ctx.setFillStyle('#999999'); //文本颜色
					ctx.setTextAlign('left') //对齐方式
					ctx.setFontSize(13) //字号
					ctx.fillText(that.activityText, 80, rect.height + 50) //文本内容及文本位置

					//绘制二维码
					ctx.drawImage(drawImageqrcodePath, rect.width - 60, rect.height + 5, 50, 50); //绘制图片
					ctx.fill();
				}).exec()
				setTimeout(function() { //必须延迟执行 不然H5不显示
					ctx.stroke();
					// //绘制结束
					ctx.draw(false, () => { //必须加上  uniapp 没这儿玩意儿 显示不出来不比原生  不加可以显示
						//保存绘图图片,产生临时文件
						uni.canvasToTempFilePath({
							canvasId: 'firstCanvas',
							quality: 1,
							complete(reset) {
								console.log("保存绘图图片,产生临时文件",reset)
								//保存图片
								uni.saveImageToPhotosAlbum({
									filePath: reset.tempFilePath,
									success(resSave) {
										setTimeout((resSave) => {
											uni.showToast({
												title: '保存成功',
												icon: 'success'
											})
										}, 2000)
									},
									fail(err) {
										console.log("err", err)
										if (err.errMsg ===
											"saveImageToPhotosAlbum:fail:auth denied" ||
											err.errMsg ===
											"saveImageToPhotosAlbum:fail auth deny" || err
											.errMsg ===
											"saveImageToPhotosAlbum:fail authorize no response"
											) {
											uni.showModal({
												title: '提示',
												content: '未授权相册,请重新授权!',
												showCancel: false,
												success: modalSuccess => {
													//获取权限
													uni.openSetting({
														success(
															settingdata
															) {
															if (settingdata
																.authSetting[
																	'scope.writePhotosAlbum'
																	]
																) {
																console
																	.log(
																		'获取权限成功,给出再次点击图片保存到相册的提示。'
																		)
															} else {
																console
																	.log(
																		'获取权限失败,给出不给权限就无法正常使用的提示'
																		)
															}
														}
													})
												}
											})
										}

									}
								})
							}
						},that)

					})
				}, 200)
			},
		

最近在做海报,本来打算使用组件的,但是我发现那些组件不怎么好用,所以自己写了一个,如果有哪里写的不对的,请大佬指点一下

上一篇:uni-app 运行模式下如何压缩css


下一篇:uniapp之APP的支付宝支付