uniapp图片加水印

1、uniapp加水印

1.1、创建画布容器

<canvas class="watermark-canvas" id="watermark-canvas" canvas-id="watermark-canvas"
			:style="{ width: canvasWidth, height: canvasHeight }" />

1.2、获取水印内容

async getLocation() {
				const zero = (item) => item < 10 ? "0" + item : item

				const time = new Date();
				const yy = time.getFullYear();
				const mm = time.getMonth() + 1;
				const dd = time.getDay();
				const hh = time.getHours();
				const MM = time.getMinutes();
				const ww = time.getDay()

				const hm = zero(hh) + ':' + zero(MM)
				const ymd = yy + '-' + zero(mm) + '-' + zero(dd)

				const {
					name: location
				} = await this.$store.dispatch('location/juGetLocation')

				return {
					hm,
					ymd,
					address: location
				}
			},

1.3、添加水印上传图片

async chooseImage(e) {
				// #ifdef APP-PLUS
				let status = await this.checkPermission()
				if (status !== 1) {
					return
				}
				// }

				// #endif
				uni.chooseImage({
					sourceType: sourceType[this.sourceTypeIndex],
					sizeType: ['compressed'],
					count: this.limit,
					success: async (res) => {
						let filePath = res.tempFilePaths[0]
						const watermark = await this.getLocation()
//压缩图片设置宽度,不然画不全
						uni.compressImage({
							src: filePath,
							quality: 80,
							success: async comres => {
								//绘制图片加水印
								let img = await this.fillTextToImg(comres.tempFilePath, watermark)
								uni.showLoading({
									title: '上传中...',
									mask: true
								})
								const arr = [img]
								// 上传图片
								const key = await this.$store.dispatch('upload/uploadFileList', arr)
								this.$emit('handleChangeKeys', {
									src: key,
									create_time: watermark.hm,
									sign_date: watermark.ymd,
									sign_local: watermark.address
								})

								uni.hideLoading()
							}
						})

					},

					fail: (err) => {}
				})
			},
			sleep(millisecond) {
				return new Promise((resolve) => {
					setTimeout(resolve, millisecond)
				})
			},
			fillTextToImg(file, watermark) {
				return new Promise((resolve, reject) => {
					uni.getImageInfo({
						src: file,
						success: async res => {
//设置画布大小,然后再画,不然会只画一部分
							this.canvasWidth = `${res.width}px`
							this.canvasHeight = `${res.height}px`
							await this.sleep(200)
							const ctx = uni.createCanvasContext('watermark-canvas', this)
							ctx.clearRect(0, 0, res.width, res.height)
							ctx.beginPath()
							ctx.drawImage(res.path, 0, 0, res.width, res.height)
							// 水印 字体大小,颜色,内容,位置
							ctx.beginPath()
							ctx.setFillStyle('#ffffff')
							const fontSize = res.width / 10
							ctx.setFontSize(fontSize)
							ctx.fillText(watermark.hm, res.width / 2 - res.width / 8, res.height / 2 - 50)
							ctx.setFontSize(res.width / 15)
							ctx.fillText(watermark.ymd, res.width / 2 - res.width / 6, res.height / 2 + 100)
							ctx.setFontSize(res.width / 17)
							ctx.fillText(watermark.address, res.width / 5 - 15, res.height / 1.5 + 50)
							// 开始绘制 (canvas -> 临时文件路径)
							ctx.draw(false, async () => {
								await this.sleep(500) // 某些平台 canvas 渲染慢,需要等待

								uni.canvasToTempFilePath({
										canvasId: 'watermark-canvas',
										destWidth: res.width,
										destHeight: res.height,
										fileType: 'jpg',
										quality: 0.8,
										success: (fileRes) => {
											resolve(fileRes.tempFilePath)
										},
										fail: (err) => {
											uni.showToast({
												title: err.errMsg,
												icon: 'none'
											})
											reject()
										},
									},
									this,
								)
							})
						},
						fail: (err) => {
							console.log('[Error getImageInfo]', err)
							uni.showToast({
								title: err.errMsg,
								icon: 'none'
							})
							reject()
						},
					})
				});
			},

1.4、设置画布位置,不让其显示

.watermark-canvas {
		transform: scale(1);
		transform-origin: 0 0;
		position: absolute;
		top: -999px;
		left: -999px;
	}

2、web端加水印(Image,FileReaderweb端才能使用)

// 获取本地图片的base64编码
// 使用在线图片链接的时候需要注意给图片设置crossOrigin属性
function fileToBase64Async(file) {
	return new Promise((resolve, reject) => {
		let reader = new FileReader();
		reader.readAsDataURL(file);
		reader.onload = (e) => {
			resolve(e.target.result);
		};
	});
}

// fillText绘制的是默认的普通实线文本,strokeText绘制的是描边文本
function fillTextToImg(base64) {
	const img = new Image();
	img.src = base64;
	img.setAttribute("crossOrigin", "Anonymous");
	return new Promise((resolve, reject) => {
		img.onload = () => {
			// 生成一个 canvas 画布;
			const canvas = document.createElement("canvas");
			canvas.width = img.width;
			canvas.height = img.height;
			// 将现有需要添加水印的图片绘制到画布上;
			const ctx = canvas.getContext("2d");
			ctx.fillRect(0, 0, canvas.width, canvas.height);
			ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
			const remFontSize = canvas.width / 35;
			ctx.font = "bolder " + remFontSize + "px Verdana";
			ctx.textAlign = "center";
			/**
			  ctx.textAlign = "center|end|left|right|start";
			  start:默认,文本在指定的位置开始。
			  end:文本在指定的位置结束。
			  center:文本的中心在指定的位置。
			  left:文本左对齐。
			  right:文本右对齐。
			  **/
			ctx.strokeStyle = "#fff";
			const name = "@AAAAAAAAAAAAA";
			const spaceH = remFontSize * 0.3;
			ctx.fillText(
				name,
				canvas.width / 2,
				canvas.height - remFontSize - spaceH
			);
			resolve(canvas.toDataURL("image/jpeg"));
		};
	});
}
相关推荐
以对_11 分钟前
uview表单校验不生效问题
前端·uni-app
Zheng1131 小时前
【可视化大屏】将柱状图引入到html页面中
javascript·ajax·html
程序猿小D1 小时前
第二百六十七节 JPA教程 - JPA查询AND条件示例
java·开发语言·前端·数据库·windows·python·jpa
john_hjy1 小时前
【无标题】
javascript
奔跑吧邓邓子2 小时前
npm包管理深度探索:从基础到进阶全面教程!
前端·npm·node.js
软件开发技术深度爱好者2 小时前
用HTML5+CSS+JavaScript庆祝国庆
javascript·css·html5
前端李易安2 小时前
ajax的原理,使用场景以及如何实现
前端·ajax·okhttp
汪子熙2 小时前
Angular 服务器端应用 ng-state tag 的作用介绍
前端·javascript·angular.js
Envyᥫᩣ3 小时前
《ASP.NET Web Forms 实现视频点赞功能的完整示例》
前端·asp.net·音视频·视频点赞
Мартин.7 小时前
[Meachines] [Easy] Sea WonderCMS-XSS-RCE+System Monitor 命令注入
前端·xss