uniapp实现水印相机

uniapp实现水印相机-livePusher

水印相机

背景

前两天拿到了一个需求,要求在内部的oaApp中增加一个卫生检查模块,这个模块中的核心诉求就是要求拍照的照片添加水印。对于这个需求,我首先想到的是直接去插件市场,下一个水印相机插件导入使用。可惜,这个oaApp的架子搭建实在是毛坯,很多时候一些简单方法,并不能直接使用。没办法,只能去找一些不那么常规的方法。在网上,找到一些方法使用livePusher和canvas来实现水印相机的效果。

核心livePusher与canvas

livePusher

官方介绍

实时音视频录制,也称直播推流。

这里使用livePusher来实现,调起系统相机,实现摄像头实时画面预览。

页面布局(页面需要是 .nvue的文件)

html 复制代码
<live-pusher id="livePusher" ref="livePusher" class="livePusher" mode="FHD" beauty="0" whiteness="0"
			:aspect="aspect" min-bitrate="1000" audio-quality="16KHz" device-position="back" :auto-focus="true"
			:muted="true" :enable-camera="true" :enable-mic="false" :zoom="false" @statechange="statechange"
			:style="{ width: windowWidth, height: windowHeight }">
</live-pusher>

onReady时创建 live-pusher 上下文 livePusherContext 对象,并初始化相机开启预览。

javascript 复制代码
this.livePusher = uni.createLivePusherContext('livePusher', this);
this.startPreview(); //开启预览并设置摄像头

//开始预览
startPreview() {
	this.livePusher.startPreview({
	success: a => {
		console.log(a)
		}
	});
},
一些踩坑的想法

这里没使用livePusher之前,我的想法是采用webView加plus-camera的方法去构建一个能够自定义的拍摄页面。为什么会有这个错误的想法,是因为我曾用过webView加plus-barcode构建了自定义的扫码页面。实践发现这个想法是错误的,因为无论是uniapp还是plus-camera使用到相机时都是调起系统的相机功能,且在app端使用内嵌相机页面的api也不支持。

拍照的操作方法
html 复制代码
<view class="menu">

			<!-- 底部菜单区域背景 -->
			<cover-image class="menu-mask" src="/static/image/13@3x.png"></cover-image>

			<!--返回键-->
			<cover-image class="menu-back" @click="back" src="/static/image/icon-back@3x.png"></cover-image>
			<!--快门键-->
			<cover-image class="menu-snapshot" @tap="snapshot" src="/static/image/condition-data-bj-circles@3x.png"></cover-image>

			<!--反转键-->
			<cover-image class="menu-flip" @tap="flip" src="/static/image/Ranking-cylindricality-top10@3x.png"></cover-image>
		</view>
javascript 复制代码
//抓拍
			snapshot() {
				//震动
				uni.vibrateShort({
					success: function() {
						console.log('success');
					}
				});

				this.livePusher.snapshot({
					success: e => {
						_this.snapshotsrc = e.message.tempImagePath
						let data = {
							url:_this.snapshotsrc,
							deptName: _this.deptName,
							time: _this.time
						}
						uni.$emit('waterMark', data);

						// 发送数据后返回上一页
						uni.navigateBack();
					}
				});
			},

			//反转
			flip() {
				this.livePusher.switchCamera();
			},
水印添加

用一个相对定位,将你的水印添加到你需要的位置,就可以试下水印和画面的实时预览啦。

canvas

前面拍照得到的照片,实际上水印并没有添加到画面中,这个时候我们需要使用canvas重新绘制,将图片和水印绘制在一起。

复制代码
		<canvas v-if="canvasShow" :style="canvasStyle" canvas-id="watermarkCanvas"></canvas>
javascript 复制代码
// 添加水印的函数
			addWatermark(imagePath, markDept, markTime) {

				return new Promise((resolve, reject) => {
					uni.getImageInfo({
						src: imagePath,
						success: (info) => {
							console.log("info.width, info.height", info.width, info.height);
							const ctx = uni.createCanvasContext('watermarkCanvas');
							ctx.drawImage(info.path, 0, 0, info.width, info.height);
							ctx.width = info.width;
							ctx.height = info.height;
							// 设置水印样式
							ctx.setFontSize(50); // 设置字体大小
							ctx.setFillStyle('white'); // 设置水印颜色
							ctx.setGlobalAlpha(0.5); // 设置水印透明度
							// 添加水印文字
							// ctx.fillText(markDept, info.width - 15, info.height - 55);
							// ctx.fillText(markTime, info.width - 15, info.height - 15);
							ctx.fillText('部门', 30, 250); // 设置水印位置
							ctx.fillText(markDept, 30, 300); // 设置水印位置
							ctx.fillText('时间', 30, 350); // 设置水印位置
							ctx.fillText(markTime, 30, 400); // 设置水印位置
							ctx.draw(true, () => {
								uni.canvasToTempFilePath({
									canvasId: 'watermarkCanvas',
									success: (res) => {
										console.log("res.tempFilePath", res.tempFilePath);
										resolve(res.tempFilePath);
									},
									fail: (err) => {
										reject(err);
									}
								});
							});
						},
						fail: (err) => {
							reject(err);
						}
					});
				});
			},

最终效果

预览画面
绘制好的水印照片

最后

水印照片的比例以及水印的位置需要自己多调试几次找到合适的比例和位置。

相关推荐
AlienZHOU5 小时前
AI Coding 时代下,我的技术面试实践分享
前端·后端·面试
Captaincc8 小时前
AI用量v0.1.11更新发布 新增 jusage doctor 诊断指令 托盘展示token 和余额 新增 AutoClaw 支持
前端·后端·vibecoding
计算机魔术师9 小时前
德国Wiki被黑后两周,OpenAI终于把模型失控的账本摊开了
前端
kyriewen10 小时前
我让 AI 当面试官面了我一轮:第 3 个追问我就卡住了(附 10 道追问清单)
前端·面试·ai编程
IT_陈寒10 小时前
Python的GIL把我坑惨了,多线程跑得比单线程还慢
前端·人工智能·后端
前端snow11 小时前
ai agent --- 多agent框架之图编排引擎-langgraph
前端
竹林81811 小时前
OmniPic Studio v3.2.1 核心技术架构与全平台发版解析文档
前端·浏览器
JamesZhang8007811 小时前
页面内存只涨不跌? 一次泄漏排查, 牵出 WeakMap 的诞生
前端
Z小明11 小时前
第 6 章 组件进阶
前端·vue.js
江华森11 小时前
HTTP请求的完整过程详解:从DNS解析到TCP挥手的微秒级实战分析
前端