uniapp图片加水印

1、uniapp加水印

1.1、创建画布容器

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

1.2、获取水印内容

famartWeek(e) {
				switch (e) {
					case 0:
						return '日'
					case 1:
						return '一'
					case 2:
						return '二'
					case 3:
						return '三'
					case 4:
						return '四'
					case 5:
						return '五'
					case 6:
						return '六'
				}
			},
			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.getDate();
				const hh = time.getHours();
				const MM = time.getMinutes();
				const ww = this.famartWeek(time.getDay())

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

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

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

1.3、添加水印上传图片

async chooseImage(e) {
				
				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,
                            compressedHeight: 1200,
							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`
							console.log(res.width, res.height);
							const bol = res.width < res.height
							let waterW = res.width
							if (bol && waterW < 650) {
								waterW = 650
							}
							if (bol && waterW > 800) {
								waterW = 800
							}
							if (!bol) {
								waterW = 800
							}
							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.font = 'bold 24px 黑体'
							// 背景
							let fw = waterW / 12
							ctx.fillStyle = "rgb(24,177,237)";
							ctx.fillRect(10, res.height / 4 * 2.8, fw * 4.2, fw * 1.4);

							ctx.textBaseline = 'top'
							ctx.setFillStyle('#ffffff')
							ctx.setFontSize(fw)
							ctx.fillText('家宴打卡', 10, res.height / 4 * 2.8 + 10)

							// 背景
							ctx.fillStyle = "#ffffff";
							ctx.fillRect(10, res.height / 4 * 2.8 + fw * 1.4, fw * 4.2, fw * 1.4);
							ctx.setFillStyle('rgb(31,53,93)')
							ctx.setFontSize(waterW / 9)
							ctx.fillText(watermark.hm, 10, res.height / 4 * 2.8 + fw * 1.4)

							ctx.setFillStyle('#ffffff')
							ctx.setFontSize(waterW / 14)
							ctx.fillText(watermark.ymd, 10, res.height / 4 * 2.8 + fw * 1.4 * 2.2)

							ctx.setFontSize(waterW / 16)
							ctx.fillText(watermark.address, 10, res.height / 4 * 2.8 + fw * 1.4 * 3)
							// 开始绘制 (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;
	}

ps:效果图

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"));
		};
	});
}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值