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"));
		};
	});
}
相关推荐
程序员爱技术43 分钟前
Vue 2 + JavaScript + vue-count-to 集成案例
前端·javascript·vue.js
并不会2 小时前
常见 CSS 选择器用法
前端·css·学习·html·前端开发·css选择器
悦涵仙子2 小时前
CSS中的变量应用——:root,Sass变量,JavaScript中使用Sass变量
javascript·css·sass
衣乌安、2 小时前
【CSS】居中样式
前端·css·css3
兔老大的胡萝卜2 小时前
ppk谈JavaScript,悟透JavaScript,精通CSS高级Web,JavaScript DOM编程艺术,高性能JavaScript pdf
前端·javascript
低代码布道师2 小时前
CSS的三个重点
前端·css
耶啵奶膘3 小时前
uniapp-是否删除
linux·前端·uni-app
王哈哈^_^5 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie5 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic6 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js