uniapp 微信小程序生成水印图片

效果

源码

html 复制代码
<template>
	<view style="overflow: hidden;">
		<camera device-position="back" flash="auto" class="camera">
			<cover-view class="text-white padding water-mark">
				<cover-view class="">{{ address }}</cover-view>
				<cover-view class="margin-top-sm">{{ date }} {{ time }}</cover-view>
			</cover-view>
			<cover-view class="camera-btn" @click="takePhoto"></cover-view>
			<cover-view class="flex justify-between align-center photos-bar" v-if="imgList.length > 0">
				<cover-view class="photos-swiper">
					<cover-view @click="viewImage(index)" class="margin-right-xs imgBox" v-for="(item,index) in imgList"
						:key="index">
						<cover-image class="imgItem" :src="item.src" mode="aspectFill"></cover-image>
						<cover-view class="del-icon" @tap.stop="delImg">❌</cover-view>
					</cover-view>
				</cover-view>
				<cover-view @click="report" class="report-btn">{{ reportBtnName }}({{ imgList.length }})</cover-view>
			</cover-view>
		</camera>
		<canvas :style="{ width: w + 'px', height: h + 'px' }" canvas-id="canvas-photo"></canvas>
	</view>
</template>

<script>
	/**
	 * @author        全易
	 * @time          2024-08-15 10:10:00
	 * @description   水印相机
	 * @param {photoMax}   			最多拍几张
	 * @param {reportBtnName}   上报摁扭的名称
	 
	 * @use	父页面这样跳:
				uni.navigateTo({
					url: "/components/watermark-camera",
					events: {
						getImages(data) {
							console.log("水印相机的照片:", data)
						}
					}
				})
	 */
	
	
	export default {
		data() {
			return {
				w: '',
				h: '',
				photoMax: 4,
				reportBtnName: "上报",
				date: "⏱️2024-08-15",
				time: "10:10:00",
				address: '📍北京 · 石景山',
				imgList: []
			}
		},
		onLoad(options) {
			this.photoMax = options.photoMax || 4;
			this.reportBtnName = options.reportBtnName || "上报";
		},
		onShow() {
			// uni.getSystemInfo({
			// 	success: function(res) {
			// 		if (res.windowWidth > res.windowHeight) {
			// 			console.log("横屏");
			// 		} else {
			// 			console.log("竖屏");
			// 		}
			// 	}
			// })


			// uni.startAccelerometer({
			// 	interval: 'game',
			// 	success() {
			// 		console.log("启用加速针:", e);
			// 		uni.onAccelerometerChange(function(res) {
			// 			console.log("加速针数据:", res);
			// 		})
			// 	}
			// })


			// uni.startGyroscope({
			// 	success(e) {
			// 		console.log("启用陀螺仪:", e);
			// 		uni.onGyroscopeChange((res) => {
			// 			console.log("陀螺仪数据:", res);
			// 		});
			// 	}
			// })


			wx.startDeviceMotionListening({
				success: (e) => {
					console.log("监听设备方向:", e);
					wx.onDeviceMotionChange((res) => {
						// console.log("设备方向:", res)
						const alpha = res.alpha;
						const beta = res.beta;
						const gamma = res.gamma;
						console.clear()
						if (Math.abs(beta) < 10 && Math.abs(gamma) < 10) {
							console.log("正竖屏");
						} else if (Math.abs(beta) > 170 && Math.abs(gamma) < 10) {
							console.log("倒竖屏");
						} else if (Math.abs(beta) < 10 && Math.abs(gamma - 90) < 10) {
							console.log("右横屏");
						} else if (Math.abs(beta) < 10 && Math.abs(gamma + 90) < 10) {
							console.log("左横屏");
						}
					});
				}
			})
		},
		methods: {
			// 拍照
			takePhoto() {
				if (this.imgList.length === this.photoMax) {
					return uni.showToast({
						icon: "error",
						title: `最多可拍${this.photoMax}张`
					});
				}

				const that = this;
				const ccc = uni.createCameraContext();
				ccc.takePhoto({
					quality: 'high',
					success: (res) => {
						console.log("拍照:", res);
						that.createWatermark(res.tempImagePath);
					}
				});
			},
			// 生成水印
			createWatermark(image) {
				const that = this;
				uni.getImageInfo({
					src: image,
					success: res => {
						that.w = res.width / 3;
						that.h = res.height / 3.01;
						const ctx = uni.createCanvasContext('canvas-photo');
						//将图片src放到cancas内,宽高为图片大小
						ctx.drawImage(image, 0, 0, that.w, that.h);
						ctx.setFontSize(12);
						ctx.setFillStyle('#FFFFFF');
						// ctx.rotate(30 * Math.PI / 180);
						const textToWidth = that.w * 0.03;

						ctx.fillText('全易', textToWidth, that.h * 0.9);

						ctx.setFontSize(10);
						ctx.fillText(that.address, textToWidth, that.h * 0.98);
						ctx.fillText(`${that.date} ${that.time}`, textToWidth, that.h * 0.94);

						ctx.draw(false, () => {
							setTimeout(() => {
								uni.canvasToTempFilePath({
									canvasId: 'canvas-photo',
									success: ctf => {
										console.log(ctf.tempFilePath);
										this.imgList.push({
											src: ctf.tempFilePath
										})
										console.log(this.imgList);
									}
								});
							}, 1000);
						});
					}
				});
			},
			// 查看照片
			viewImage(index) {
				uni.previewImage({
					current: index,
					urls: this.imgList.map(item => {
						return item.src
					})
				});
			},
			delImg(e) {
				uni.showModal({
					title: '删除提醒',
					content: '确定要删除这张照片吗?',
					success: res => {
						if (res.confirm) {
							this.imgList.splice(e.currentTarget.dataset.index, 1);
						}
					}
				});
			},
			// 上报父页面
			report() {
				const that = this;
				uni.navigateBack({
					success() {
						const eventChannel = that.getOpenerEventChannel();
						eventChannel.emit('getImages', {
							images: that.imgList
						});
					}
				});
			}
		}
	}
</script>

<style scoped lang="scss">
	.camera {
		width: 100vw;
		height: 100vh;
	}

	.water-mark {}

	.camera-btn {
		width: 120rpx;
		height: 120rpx;
		line-height: 120rpx;
		border: 6rpx #FFFFFF solid;
		border-radius: 50%;
		padding: 8rpx;
		position: absolute;
		left: calc(50% - 60rpx);
		bottom: 210rpx;

		&::after {
			content: " ";
			display: block;
			width: 89%;
			height: 89%;
			position: absolute;
			top: 5%;
			left: 5%;
			border-radius: 50%;
			background-color: #FFFFFF;
		}
	}

	.photos-bar {
		width: 100%;
		height: 170rpx;
		box-sizing: border-box;
		padding: 20rpx 30rpx 40rpx;
		position: absolute;
		bottom: 0;
		left: 0;
		background-color: rgba(0, 0, 0, .8);

		.photos-swiper {
			width: 80%;
			overflow-x: auto;
			height: -webkit-fill-available;

			.imgBox {
				width: 110rpx;
				height: 110rpx;
				position: relative;
				display: inline-block;

				.del-icon {
					position: absolute;
					right: 0;
					top: 0;
					padding: 2px;
					background-color: rgba(0, 0, 0, 0.5);
				}

				.imgItem {
					width: 110rpx;
					height: 110rpx;
				}
			}
		}

		.report-btn {
			height: 68rpx;
			line-height: 68rpx;
			text-align: center;
			color: #FFFFFF;
			box-sizing: border-box;
			padding: 0rpx 20rpx;
			border-radius: 10rpx;
			background-color: #2157FF;
		}
	}

	#canvas-photo {
		position: fixed;
		top: -999999px;
	}
</style>
相关推荐
骆晨学长31 分钟前
基于springboot的智慧社区微信小程序
java·数据库·spring boot·后端·微信小程序·小程序
平凡シンプル4 小时前
安卓 uniapp跨端开发
android·uni-app
李宥小哥4 小时前
微信小程序07-开发进阶
微信小程序·小程序·notepad++
艾小逗5 小时前
uniapp快速入门教程,内容来源于官方文档,仅仅记录快速入门需要了解到的知识点
小程序·uni-app·app·es6
2401_8459375315 小时前
PHP一键约课高效健身智能健身管理系统小程序源码
微信·微信小程序·小程序·微信公众平台·微信开放平台
程序员入门进阶17 小时前
基于微信小程序的科创微应用平台设计与实现+ssm(lw+演示+源码+运行)
微信小程序·小程序
鸭子嘎鹅子呱20 小时前
uniapp使用高德地图设置marker标记点,后续根据接口数据改变某个marker标记点,动态更新
uni-app·map·高德地图
计算机源码社1 天前
分享一个基于微信小程序的居家养老服务小程序 养老服务预约安卓app uniapp(源码、调试、LW、开题、PPT)
android·微信小程序·uni-app·毕业设计项目·毕业设计源码·计算机课程设计·计算机毕业设计开题
双普拉斯1 天前
微信小程序点赞动画特效实现
nginx·微信小程序·notepad++
程序员阿龙1 天前
【2025】基于微信小程序的网上点餐系统设计与实现、基于微信小程序的智能网上点餐系统、微信小程序点餐系统设计、智能点餐系统开发、微信小程序网上点餐平台设计
微信小程序·小程序·毕业设计·订单管理·在线点餐·订单跟踪·在线支付