uni-app实现水印相机

这篇具有很好参考价值的文章主要介绍了uni-app实现水印相机。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

效果展示

点击“拍照”,拍照成功后在底部生成已经添加上水印的图片,点击图片查看图片

uniapp 水印相机,uni-app,业务需求,uni-app,相机

uniapp 水印相机,uni-app,业务需求,uni-app,相机

结构与样式

结构

<template>
	<view>
		<camera :device-position="device" :flash="flash" @error="error" :style="{ width: '100%',position: 'relative', height: getHeight + 'px' }">
			<cover-view class="topBox">
                <!-- 时间 -->
				<cover-view class="topItem">{{nowTime2}}</cover-view>
                <!-- 日期 -->
				<cover-view class="topItem">{{nowTime}}</cover-view>
                <!-- 地址 -->
				<cover-view class="topItem">{{address}}</cover-view>
			</cover-view>

            <!-- 旋转摄像头 -->
			<cover-image @click="xzBtn" class="xzImg" src="https://cdn.zhoukaiwen.com/xz.png"></cover-image>
            <!-- 打开/关闭 闪关灯 -->
			<cover-image @click="sgdBtn" class="sgdImg" :src="sgdUrl"></cover-image>
            <!-- 拍照 -->
			<cover-view class="cameraBtn" @click="takePhoto">
				<cover-view class="cameraBtn2"></cover-view>
			</cover-view>
          
            <!-- 底部预览生成图片 -->
			<cover-view class="bottomBg" v-if="imgList.length > 0">
				<cover-view>
					<cover-view @click="ViewImage(index)" class="imgBox" v-for="(item,index) in imgList" :key="index">
						<cover-image class="imgItem" :src="item.src" mode="aspectFill"></cover-image>
						<cover-view class="cu-tag" @tap.stop="DelImg" :data-index="index">
							<cover-image class="iconClose" src="https://cdn.zhoukaiwen.com/icon_close.png" mode="aspectFill"></cover-image>
						</cover-view>
					</cover-view>
				</cover-view>
			</cover-view>
		</camera>

        <!-- canvas元素,利用它的功能,实现添加水印 -->
		<view style="position: absolute;top: -999999px;">
          <view>
            <canvas :style="{ width: w, height: h }" canvas-id="firstCanvas"></canvas>
          </view>
		</view>

	</view>
</template>

为了让自定义的按钮如:旋转镜头、打开/关闭 闪光灯、拍摄等能够位于camera 组件上层,所以容器都采用 cover-view、cover-image

样式

	.topBox {
		width: 750rpx;
		box-sizing: border-box;
		padding: 30rpx;
		color: #EEEEEE;
		font-size: 34rpx;

		.topItem {
			width: 100%;
			white-space: pre-wrap;
			margin-bottom: 15rpx;
		}
	}

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

	.cameraBtn2 {
		width: 100%;
		height: 100%;
		border-radius: 50%;
		background-color: #FFFFFF;
		text-align: center;
		color: #007AFF;
	}

	.xzImg {
		width: 52rpx;
		height: auto;
		position: absolute;
		right: 44rpx;
		bottom: 580rpx;
	}

	.sgdImg {
		width: 40rpx;
		height: auto;
		position: absolute;
		right: 50rpx;
		bottom: 450rpx;
	}

	.bottomBtn {
		width: 100%;
		height: 150rpx;
		padding-bottom: 15rpx;
		position: absolute;
		bottom: 0;
		left: 0;
		text-align: center;
		display: flex;
		justify-content: space-between;

		.btn {
			width: 30%;
			height: 150rpx;
			font-size: 34rpx;
			color: #FFFFFF;
			line-height: 150rpx;
		}
	}

	.bottomBg {
		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);
		display: flex;
		justify-content: space-between;
		align-items: center;

		.imgBox {
			width: 110rpx;
			height: 110rpx;
			float: left;
			margin-right: 40rpx;
			position: relative;

			.cu-tag {
				position: absolute;
				right: 0;
				top: 0;
				border-bottom-left-radius: 2px;
				padding: 3px 5px;
				height: auto;
				background-color: rgba(0, 0, 0, 0.5);
				font-size: 10px;
				vertical-align: middle;
				font-family: Helvetica Neue, Helvetica, sans-serif;
				white-space: nowrap;
				color: #ffffff;
			}
		}

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

	.iconClose {
		width: 20rpx;
		height: 20rpx;
	}

绑定数据

data() {
  return {
    getHeight: '200', // camera 组件高度
    device: 'back', //前置或后置摄像头,值为front, back
    flash: 'off', // 闪光灯,值为auto, on, off
    nowTime: '', //日期
    nowTime2: '', //时间
    address: '', //当前地址信息
    sgdUrl: 'https://cdn.zhoukaiwen.com/sgd.png', // 闪光灯图片地址
    imgList: [ // 底部预览图片的列表
      // {
      // 	src: "https://cdn.zhoukaiwen.com/angular.jpg"
      // }
    ],
    w: '', // canvas 元素宽度
    h: '' // canvas 元素高度
  }
},

逻辑代码

需要提前下载腾讯地图微信小程序JavaScript SDK,实现定位功能

// 引入微信小程序JavaScript SDK
import QQMapWX from "@/common/qqmap-wx-jssdk";


onLoad() {
  const that = this;
  var qqmapsdk;
  // 获取系统信息,为 camera 组件设置高度
  uni.getSystemInfo({
    success: function(res) {
      that.getHeight = res.windowHeight;
    }
  });
  // 获取当前日期时间
  this.getTime();
  // 获取当前位置信息 
  uni.getLocation({
    type: 'wgs84',
    success: function(res) {
      console.log('当前位置的经度:' + res.longitude);
      console.log('当前位置的纬度:' + res.latitude);

      qqmapsdk = new QQMapWX({
        key: "xxxxxxxxxxxxxxxxxxx" //自己申请的腾讯地图key
      });
      // 根据经纬度反解析出地址名称
      qqmapsdk.reverseGeocoder({
        location: {
          latitude: res.latitude,
          longitude: res.longitude
        },
        success(addressRes) {
          that.address = addressRes.result.address;
        },
        fail(res) {}
      });
    }
  });

},
methods: {
  // 旋转摄像头
  xzBtn() {
    if (this.device == 'front') {
      this.device = 'back'
    } else {
      this.device = 'front'
    }
  },
  // 打开/关闭 闪光灯
  sgdBtn() {
    if (this.flash == 'off') {
      this.flash = 'on'
      this.sgdUrl = 'https://cdn.zhoukaiwen.com/sgd_on.png'
    } else {
      this.flash = 'off'
      this.sgdUrl = 'https://cdn.zhoukaiwen.com/sgd.png'
    }
  },
  // 删除水印照片
  DelImg(e) {
    uni.showModal({
      content: '确定要删除这张照片吗?',
      cancelText: '取消',
      confirmText: '确认',
      success: res => {
        if (res.confirm) {
          this.imgList.splice(e.currentTarget.dataset.index, 1)
        }
      }
    })
  },
  // 查看照片
  ViewImage(index) {
    const imgList = [this.imgList[index].src];
    uni.previewImage({
      urls: imgList
    });
  },
  // 点击拍照
  takePhoto() {
    var that = this;
    if (this.imgList.length < 3) {
      // 创建并返回 camera 组件的上下文 cameraContext 对象
      const ctx = uni.createCameraContext();
      // 拍照
      ctx.takePhoto({
        quality: 'high', // 图片质量高
        success: (res) => {
          var tempImagePath = res.tempImagePath; // 临时图片路径
          // 获取图片信息
          uni.getImageInfo({
            src: res.tempImagePath,
            success: ress => {
              that.w = ress.width / 3 + 'px'; // 设置 canvas 元素宽度
              that.h = ress.height / 3.01 + 'px'; // 设置 canvas 元素高度
              let ctx = uni.createCanvasContext('firstCanvas'); /** 创建画布 */
              //将图片绘制到cancas内
              ctx.drawImage(res.tempImagePath, 0, 0, ress.width / 3, ress.height / 3);
              
              ctx.setFontSize(10); // 设置字体大小为 10px
              ctx.setFillStyle('#FFFFFF'); // 设置颜色为白色
              
              let textToWidth = (ress.width / 3) * 0.03; // 绘制文本的左上角x坐标位置
              let textToHeight1 = (ress.height / 3) * 0.94; // 绘制文本的左上角y坐标位置
              let textToHeight2 = (ress.height / 3) * 0.98;
              
              // 绘制日期和时间
              ctx.fillText(that.nowTime + ' ' + that.nowTime2, textToWidth, textToHeight1);
              // 绘制地址
              ctx.fillText(that.address, textToWidth, textToHeight2);

              // 绘制完成后,在下一个事件循环将 canvas 内容导出为临时图片地址
              ctx.draw(false, () => {
                setTimeout(() => {
                  uni.canvasToTempFilePath({
                    canvasId: 'firstCanvas',
                    success: res1 => {
                      tempImagePath = res1.tempFilePath
                      this.imgList.push({
                        src: tempImagePath
                      })
                    }
                  });
                }, 1000);
              });
            }
          });
        }
      });
    } else {
      uni.showToast({
        title: '最大上传3张照片',
        duration: 2000,
        icon: 'none'
      });
    }
  },
  // 用户不允许使用摄像头时触发
  error(e) {
    console.log(e.detail);
  },
  // 获取日期时间
  getTime: function() {
    var date = new Date(),
        year = date.getFullYear(),
        month = date.getMonth() + 1,
        day = date.getDate(),
        hour = date.getHours() < 10 ? "0" + date.getHours() : date.getHours(),
        minute = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes(),
        second = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
    month >= 1 && month <= 9 ? (month = "0" + month) : "";
    day >= 0 && day <= 9 ? (day = "0" + day) : "";
    var timer = year + '年' + month + '月' + day + '日';
    var timer2 = hour + ':' + minute + ':' + second;
    this.nowTime = timer;
    this.nowTime2 = timer2;
  }
}

注意

本文章代码 90% 以上都是参考开源项目 前端铺子,如帮助到你,可以去大佬项目 gitee地址 点个 star文章来源地址https://www.toymoban.com/news/detail-732290.html

到了这里,关于uni-app实现水印相机的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Uni-App】uniapp使用uview实现弹出键盘输入密码/验证码功能

    组件使用的是uview组件,Keyboard 键盘和MessageInput 验证码输入两个组件配合使用。 通过mode参数定义键盘的类型,v-model绑定一个值为布尔值的变量,我绑定的是showKeyboard变量,控制键盘的弹出与收起; mode = number (默认值)为数字键盘,此时顶部工具条中间的提示文字为\\\"数字键盘

    2023年04月16日
    浏览(73)
  • 『UniApp』uni-app-打包成App

    大家好,我是 BNTang, 在上一节文章中,我给大家详细的介绍了如何将我开发好的项目打包为微信小程序并且发布到微信小程序商店 趁热打铁,在来一篇文章,给大家详细的介绍如何将项目打包成APP。 打包 App 也是一样的,首先需要配置关于 App 应用的基础信息,打开 manifest

    2024年02月04日
    浏览(108)
  • 【UniApp】-uni-app-网络请求

    经过上个章节的介绍,大家可以了解到 uni-app-pinia存储数据的基本使用方法 那本章节来给大家介绍一下 uni-app-网络请求 的基本使用方法 首先我们打开官方文档,我先带着大家看一下官方文档的介绍:https://uniapp.dcloud.net.cn/api/request/request.html 从官方文档中我们可以看到,可以

    2024年02月04日
    浏览(53)
  • 【UniApp】-uni-app-打包成网页

    经过上一篇文章的介绍,已经将这个计算器的计算功能实现了,接下来就是我们项目当中的一个发包上线阶段,我模拟一下,目的就是为了给大家介绍一下,uni-app是如何打包成网页的。 除了可以打包成网页,uni-app还可以打包成小程序、App、H5、快应用等等,后面在单独开文

    2024年02月04日
    浏览(72)
  • Uniapp uni-app学习与快速上手

    个人开源uni-app开源项目地址:准备中 在线展示项目地址:准备中 什么是uni-app uni,读 you ni ,是统一的意思。 Dcloud即数字天堂(北京)网络技术有限公司是W3C成员及HTML5中国产业联盟发起单位,致力于推进HTML5发展构建,HTML5生态。 2012年,DCloud开始研发小程序技术,优化webvie

    2024年02月09日
    浏览(64)
  • 【uni-app】UniApp实现微信小程序中拨打手机电话和长按加微信客服好友(完整代码示例)

    UniApp实现微信小程序中拨打手机电话和长按加微信客服好友(完整代码示例)

    2024年02月11日
    浏览(69)
  • uni-app 调用相机或相册图片并转为base64格式上传图片

    1、调用相机或相册上传图片 2、图片文件转base64 (1)下载插件 (2)页面引入插件 3、image-tools/index.js源码

    2024年02月11日
    浏览(62)
  • 【uni-app教程】四、UniAPP 路由配置及页面跳转

    uni-app 页面路由为框架统一管理,开发者需要在pages.json里配置每个路由页面的路径及页面样式。类似小程序在 app.json 中配置页面路由一样。所以 uni-app 的路由用法与 Vue Router 不同,如仍希望采用 Vue Router 方式管理路由,可在插件市场搜索 Vue-Router。 uni-app 有两种页面路由跳转

    2024年01月16日
    浏览(77)
  • 【UniApp】-uni-app-项目实战页面布局(苹果计算器)

    经过前面的文章介绍,基本上 UniApp 的内容就介绍完毕了 那么从本文开始,我们就开始进行一个项目的实战 这次做的项目是苹果计算器,这个项目的难度不是很大,但是也不是很简单,适合练手 打开 HBuilderX,点击左上角 文件 - 新建 - 项目 : 项目创建完毕之后,首先来分析

    2024年02月04日
    浏览(67)
  • 在 WebStorm 中开发 uni-app - 用vue2实现手机APP(apk) + 微信小程序项目开发方案 webstorm开发的uniapp + hbuilderx进行app 小程序打包

    我们主要分析了如下小程序开发框架,主要包括: 框架 技术栈 案例 微信小程序 支付宝小程序 百度小程序 头条小程序 H5 App uni-app Vue 丰富 ⭕ ⭕️ ⭕️ ⭕ ⭕️ ⭕ Taro React 丰富 ⭕ ⭕ ⭕ ⭕ ⭕ ⭕ wepy Vue 丰富 ⭕ ❌ ❌ ❌ ❌ ❌ mpvue Vue 丰富 ⭕ ❌ ❌ ❌ ⭕️ ❌  首先,就要排

    2024年02月05日
    浏览(97)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包