在實際開發(fā)的項目中,我們有時候會遇到相機拍照上傳照片的時候需要帶有水印的功能。下面整理了我在自己的項目中做的水印相機(完整源碼)功能實戰(zhàn)分享給大家。
水印中內(nèi)容包含如下(實際包含的內(nèi)容根據(jù)你的實際需求而定,這里只是以我的項目需求為例):
- 具體日期時間,如:2023-05-25 12:00:00?星期四
- 地理位置,如:江蘇省南京市雨花臺區(qū)軟件大道19號
- 經(jīng)緯度,如:緯度: 32.08405200000000,經(jīng)度: 118.76358600000000
------↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓---上源碼---↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓------
1.?申請功能(父組件)文章來源:http://www.zghlxwxcb.cn/news/detail-773573.html
<template>
<view class="container">
<!-- 背景漸變 -->
<view class="bg_gradient"></view>
<!-- 申報信息 -->
<view class="applyInfo">
<view class="applyTable">
<u-form :model="model1" ref="form1">
<u-form-item label="申請單位(人)" labelWidth="130rpx" borderBottom prop="name">
<u-input
clearable
placeholder="請輸入申請單位(人)"
v-model="model1.name"
></u-input>
</u-form-item>
<u-form-item label="通訊地址" labelWidth="130rpx" borderBottom prop="address">
<u-input
clearable
placeholder="請輸入通訊地址"
v-model="model1.address"
></u-input>
</u-form-item>
<u-form-item label="聯(lián)系電話" labelWidth="130rpx" borderBottom prop="tel">
<u-input
clearable
placeholder="請輸入聯(lián)系電話"
v-model="model1.tel"
></u-input>
</u-form-item>
<u-form-item label="調(diào)入地點" labelWidth="130rpx" borderBottom prop="addressIn" @click="addressShow = true">
<u-input disabled disabledColor="#fff" placeholder="請選擇省市區(qū)" v-model="model1.addressIn"></u-input>
<!-- 省市區(qū)選擇器 -->
<u-picker
ref="uPicker"
:show="addressShow"
:columns="addressColumn"
@change="addressChange"
@confirm="addressConfirm"
@cancel="addressShow = false"
></u-picker>
</u-form-item>
<u-form-item label="收貨單位(人)" labelWidth="130rpx" borderBottom prop="nameOut">
<u-input
clearable
placeholder="請輸入收貨單位(人)"
v-model="model1.nameOut"
></u-input>
</u-form-item>
<u-form-item label="收貨人" labelWidth="130rpx" borderBottom prop="nameOut2">
<u-input
clearable
placeholder="請輸入收貨人姓名"
v-model="model1.nameOut2"
></u-input>
</u-form-item>
<u-form-item label="身份證號" labelWidth="130rpx" borderBottom prop="idCard">
<u-input
clearable
placeholder="請輸入身份證號碼"
v-model="model1.idCard"
></u-input>
</u-form-item>
<u-form-item label="手機號" labelWidth="130rpx" borderBottom prop="telOut">
<u-input
clearable
placeholder="請輸入手機號"
v-model="model1.telOut"
></u-input>
</u-form-item>
<u-form-item label="調(diào)入時間" labelWidth="130rpx" borderBottom prop="applyTime" @click="datetimeShow=true">
<u-input disabled disabledColor="#fff" placeholder="請選擇時間" v-model="model1.applyTime"></u-input>
<!-- 時間選擇器 -->
<u-datetime-picker
ref="datetimePicker"
mode="datetime"
:formatter="formatter2"
:show="datetimeShow"
v-model="model1.timeIn"
@confirm="datetimeConfirm"
@cancel="datetimeShow=false"
></u-datetime-picker>
</u-form-item>
<u-form-item label="車牌號" labelWidth="130rpx" borderBottom prop="carNo">
<u-input
clearable
placeholder="請輸入車牌號"
v-model="model1.carNo"
></u-input>
</u-form-item>
<button style="margin-top: 10px;" @click="addShow=true">新增產(chǎn)品</button>
<view class="addProduct" v-for="it,index in model1.treeInfoVO" :key="index">
<view class="deleteProduct" @click="delProduct(it)">x</view>
<view class="p">
<view>產(chǎn)品名稱:</view>
<view>{{ it.tname }}</view>
</view>
<view class="p">
<view>品名/材種:</view>
<view>{{ it.kind }}</view>
</view>
<view class="p">
<view>規(guī)格:</view>
<view>{{ it.spec }}</view>
</view>
<view class="p">
<view>數(shù)量:</view>
<view>{{ it.num }}</view>
</view>
<view class="p">
<view>備注:</view>
<view>{{ it.remark }}</view>
</view>
</view>
</u-form>
</view>
<view class="title">
<view class="up">
<b>*</b><view>照片說明</view>
</view>
<view style="margin: 20rpx 0;color: #444;">
<text>車頭正面照、車頭左側(cè)45度照、車頭右側(cè)45度照、車尾正面照、車尾左側(cè)45度照、車尾右側(cè)45度照、細(xì)節(jié)照1、細(xì)節(jié)照2</text>
</view>
</view>
<view style="margin: 3px 0 10px;"><u-line></u-line></view>
<view class="photo">
<view class="up">
<b>*</b><view>照片列表</view>
</view>
<view class="down">
<watermark @cameraCloseEvent="cameraCloseBtn" @cameraEvent="cameraBtn" @finishEvent="afterReadHandler" @deleteEvent="deletePhoto" :imgUrls="imgUrls" :submitDisabled="submitDisabled"></watermark>
</view>
</view>
<!-- 提交按鈕 -->
<view class="submitBtn">
<view>
<u-button type="primary" shape="circle" color="#00c39c" text="提交" :disabled="submitDisabled" @click="submit"></u-button>
</view>
</view>
</view>
<!-- 新增產(chǎn)品模態(tài)框 -->
<u-modal
:show="addShow"
title="植物產(chǎn)品"
showCancelButton
@cancel="addCancel"
@confirm="addConfirm"
>
<view style="display: flex;flex-direction: column;">
<u-form :model="model2" ref="form2">
<u-form-item label="產(chǎn)品名稱" labelWidth="120rpx" borderBottom prop="tname">
<u-input placeholder="請輸入植物產(chǎn)品名稱" v-model="model2.tname"></u-input>
</u-form-item>
<u-form-item label="品名/材種" labelWidth="130rpx" borderBottom prop="kind">
<u-input placeholder="請輸入品名/材種" v-model="model2.kind"></u-input>
</u-form-item>
<u-form-item label="規(guī)格類型" labelWidth="120rpx" borderBottom prop="" @click="specShow=true">
<u-input disabled disabledColor="#fff" placeholder="請選擇規(guī)格類型" v-model="specVal"></u-input>
<u-picker
title="規(guī)格類型"
:show="specShow"
:columns="specColumns"
@confirm="specSelect"
@cancel="specShow = false"
></u-picker>
</u-form-item>
<u-form-item label="規(guī)格" labelWidth="120rpx" borderBottom prop="spec">
<u-input placeholder="請輸入規(guī)格內(nèi)容" v-model="model2.spec"></u-input>
</u-form-item>
<u-form-item label="數(shù)量" labelWidth="120rpx" borderBottom prop="num">
<u-input placeholder="請輸入數(shù)量" v-model="model2.num"></u-input>
</u-form-item>
<u-form-item label="備注" labelWidth="100rpx" borderBottom prop="remark">
<u-textarea count maxlength="80" height="75" placeholder="請輸入備注內(nèi)容" v-model="model2.remark"></u-textarea>
</u-form-item>
</u-form>
</view>
</u-modal>
<!-- 提示信息 -->
<u-toast ref="uToast"></u-toast>
</view>
</template>
<script>
import {sendApplication,getAddress,getInformation,getImgsByIds} from '../../../api/applicant/index.js'
import watermark from './watermark.vue'
export default {
components: {watermark},
data() {
return {
model1: {
name: '', // 申請單位(人)
address: '', // 通訊地址
tel: '', // 聯(lián)系電話
addressIn: '', // 調(diào)入地點
nameOut: '', // 收貨單位(人)
nameOut2: '', // 收貨人
idCard: '', // 身份證號
telOut: '', // 手機號
timeIn: '', // 調(diào)入時間
carNo: '', // 車牌號
treeInfoVO: [],// 新增產(chǎn)品內(nèi)容
title: '', // 標(biāo)題內(nèi)容
rid: '', // 上傳照片
applyTime: '', // 時間選擇器選擇時間后頁面展示的調(diào)入時間
},
rules1: {
'name': {
whitespace: true,
required: true,
message: '請輸入申請單位(人)',
trigger: ['blur', 'change']
},
'address': {
whitespace: true,
required: true,
message: '請輸入通訊地址',
trigger: ['blur', 'change']
},
'tel': [
{
required: true,
message: '請輸入聯(lián)系電話',
trigger: ['blur', 'change']
},
{
pattern: /(^\d{3}-\d{8}$|^\d{4}-\d{7}$)|(^1[3-9]\d{9}$)/,
message: `電話號碼規(guī)則錯誤,正確格式:
XXXX-XXXXXXX、XXX-XXXXXXXX
或者11位手機號碼`,
trigger: ['blur']
}
],
'addressIn': {
required: true,
message: '請選擇省市區(qū)',
trigger: ['blur', 'change']
},
'nameOut': {
whitespace: true,
required: true,
message: '請輸入收貨單位(人)',
trigger: ['blur', 'change']
},
'nameOut2': {
whitespace: true,
required: true,
message: '請輸入收貨人',
trigger: ['blur', 'change']
},
'idCard': [
{
required: true,
message: '請輸入身份證號',
trigger: ['blur', 'change']
},
{
pattern: /^[1-9]\d{5}(19\d{2}|20[0-2][0-9])(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[0-9Xx]$/,
message: `請輸入正確的身份證號碼`,
trigger: ['blur']
}
],
'telOut': [
{
required: true,
message: '請輸入手機號',
trigger: ['blur', 'change']
},
{
pattern: /^1[3-9]\d{9}$/,
message: "請輸入合法的手機號碼",
trigger: ['blur']
}
],
'carNo': [
{
pattern: /^([京津滬渝冀豫云遼黑湘皖魯新蘇浙贛鄂桂甘晉蒙陜吉閩貴粵青藏川寧瓊使領(lǐng)A-Z]{1}[a-zA-Z](([DF]((?![IO])[a-zA-Z0-9](?![IO]))[0-9]{4})|([0-9]{5}[DF]))|[京津滬渝冀豫云遼黑湘皖魯新蘇浙贛鄂桂甘晉蒙陜吉閩貴粵青藏川寧瓊使領(lǐng)A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9掛學(xué)警港澳]{1})$/,
message: "請輸入合法的車牌號碼",
trigger: ['blur']
}
],
'applyTime': {
required: true,
message: '請選擇時間',
trigger: ['blur', 'change']
},
},
model2: {
tname: '', // 植物產(chǎn)品名稱
kind: '', // 品名/材種
spec: '', // 規(guī)格
num: '', // 數(shù)量
remark: '',// 備注
},
rules2: {
'tname': {
whitespace: true,
required: true,
message: '請輸入植物產(chǎn)品名稱',
trigger: ['blur', 'change']
},
'kind': {
whitespace: true,
required: true,
message: '請輸入品名/材種',
trigger: ['blur', 'change']
},
'spec': [
{
whitespace: true,
required: true,
message: '請輸入規(guī)格內(nèi)容',
trigger: ['blur', 'change']
}
],
'num': [
{
required: true,
message: '請輸入數(shù)量',
trigger: ['blur', 'change']
},
{
pattern: /^[0-9]+$/,
message: "數(shù)量必須是非負(fù)整數(shù)",
trigger: ['blur']
}
]
},
datetimeShow: false, // 是否顯示 時間選擇器
addressShow: false, // 是否顯示 省市區(qū)選擇器
addressColumn: [['請選擇'],['請選擇'],['請選擇']],// 省市區(qū)
province: [], // 省
city: [], // 市
area: [], // 區(qū)
addShow: false, // 是否顯示 新增產(chǎn)品模態(tài)框
specShow: false, // 是否顯示 規(guī)格類型選擇器
specColumns: [['胸徑','地徑','冠幅','其他']],
specVal: '胸徑', // 規(guī)格類型
imgsRelation: [], // 存放(水印照片圖片路徑與rid對應(yīng)關(guān)系)數(shù)組
submitDisabled: false,// 提交按鈕是否禁用
imgUrls: [], // 照片url
imgIds: [], // 照片id
isSubmit: false, // 是否執(zhí)行了(提交按鈕)
}
},
methods: {
/* 通過傳進來的rid獲取照片 */
getImgs() {
getImgsByIds({ids: this.imgIds}).then(res=>{
if(res.code==200) {
this.imgUrls = [];
let resData = res.data;
for(let i=0;i<resData.length;i++) {
this.imgUrls.push(resData[i].url);
for(let ii=0;ii<this.imgIds.length;ii++) {
if(i==ii) {
let relation = {[resData[i].url]: this.imgIds[ii]}; //水印照片圖片路徑與rid對應(yīng)關(guān)系
this.imgsRelation.push(relation);
}
}
}
}
})
},
/* 時間選擇器確認(rèn) */
datetimeConfirm(val) {
this.model1.timeIn = val.value;
let d = new Date(this.model1.timeIn*1);
this.model1.applyTime = d.getFullYear() +'年'+ (d.getMonth() + 1) +'月'+ d.getDate() +'日'+ d.getHours() +'時'+ d.getMinutes() +'分';
this.$refs.form1.validateField('applyTime');
this.datetimeShow = false;
},
/* 時間格式化 */
formatter2(type, value) {
if (type === 'year') {return `${value}年`};
if (type === 'month') {return `${value}月`};
if (type === 'day') {return `${value}日`};
if (type === 'hour') {return `${value}時`};
if (type === 'minute') {return `${value}分`};
return value;
},
/* 省市區(qū)選擇器確認(rèn) */
addressConfirm(e) {
if(e.value[0]=='請選擇') {
this.addressShow = false;
} else {
if(e.value[1] == '請選擇' || e.value[2] == '請選擇') {
this.$refs.uToast.show({
type: 'error',
message: '省市區(qū)不完整',
duration: 2500,
})
} else {
this.addressShow = false;
this.model1.addressIn = e.value[0] + e.value[1] + e.value[2];
this.$refs.form1.validateField('addressIn');
}
}
},
/* 省市區(qū)選擇器改變 */
async addressChange(e) {
// 當(dāng)?shù)谝涣?省)值發(fā)生變化時
if (e.columnIndex === 0) {
this.addressColumn[1].splice(1);
this.addressColumn[2].splice(1);
if(e.index==0) return;
this.$refs.uPicker.setColumnValues(1, this.addressColumn[1][e.index])
// 選中的省份數(shù)據(jù)
let selectProvince = this.province.find(item=>{
return item.address == e.value[0];
})
// 獲取城市列表
await getAddress({addressType: 2,code: selectProvince.code}).then(res=>{
if(res.code==200) {
this.city = res.data;
res.data.forEach(item=>{
this.addressColumn[1].push(item.address);
})
}
})
}
// 當(dāng)?shù)诙?市)值發(fā)生變化時
if (e.columnIndex === 1) {
this.addressColumn[2].splice(1);
if(e.index==0) return;
this.$refs.uPicker.setColumnValues(2, this.addressColumn[2][e.index])
// 選中的城市數(shù)據(jù)
let selectCity = this.city.find(item=>{
return item.address == e.value[1];
})
// 獲取區(qū)域列表
await getAddress({addressType: 3,code: selectCity.code}).then(res=>{
if(res.code==200) {
this.area = res.data;
res.data.forEach(item=>{
this.addressColumn[2].push(item.address);
})
}
})
}
},
/* 關(guān)閉水印相機觸發(fā) */
cameraCloseBtn() {
this.submitDisabled = false;
},
/* 點擊水印相機觸發(fā) */
cameraBtn() {
uni.setStorageSync('cacheApplyInfo',JSON.stringify(this.model1));
this.submitDisabled = true;
},
/* 照片完成后的處理函數(shù) */
afterReadHandler(e) {
uni.uploadFile({
url: `${this.$upload}`,
filePath: e,
name: 'file',
header: {
Authorization: uni.getStorageSync('token'),
'Content-Type': 'multipart/form-data',
},
success: res => {
if(res.statusCode==200) {
if(this.model1.rid=='') {
this.model1.rid += JSON.parse(res.data).data.id;
} else {
this.model1.rid += ',' + JSON.parse(res.data).data.id;
}
let relation = {[e]: JSON.parse(res.data).data.id}; //水印照片圖片路徑與rid對應(yīng)關(guān)系
this.imgsRelation.push(relation);
this.submitDisabled = false;
}
}
})
},
/* 刪除照片 */
deletePhoto(srcVal) {
let tempArr = this.model1.rid.split(',');
let tempRid = '';
this.imgsRelation.forEach(outIt=>{
for(let inIt in outIt) {
if(inIt == srcVal) {
tempRid = outIt[inIt];
}
}
})
tempArr = tempArr.filter(item=>{
if(item!=tempRid) return item;
})
this.model1.rid = tempArr.join(',');
},
/* 規(guī)格類型下拉選擇觸發(fā) */
specSelect(val) {
this.specShow = false;
this.specVal = val.value[0];
},
/* 新增產(chǎn)品取消 */
addCancel() {
this.addShow = false;
this.model2.tname = "";
this.model2.kind = "";
this.model2.spec = "";
this.model2.num = "";
this.model2.remark = "";
this.$refs.form2.clearValidate();
},
/* 新增產(chǎn)品確定 */
addConfirm() {
this.$refs.form2.validate().then(() => {
this.model2.spec = this.specVal +":"+ this.model2.spec;
this.model1.treeInfoVO.push({...this.model2});
this.addCancel();
}).catch(()=>{});
},
/* 刪除產(chǎn)品 */
delProduct(itVal) {
this.model1.treeInfoVO = this.model1.treeInfoVO.filter(item=>{
if(itVal!=item) return item;
})
},
/* 提交 */
submit() {
this.$refs.form1.validate().then(() => {
if(this.model1.treeInfoVO.length==0) {
this.$refs.uToast.show({type: 'error',message: '請新增產(chǎn)品'});
} else if(this.model1.rid.split(',').length<2) {
this.$refs.uToast.show({type: 'error',message: '照片不得少于2張'});
} else {
this.submitDisabled = true;
this.model1.title = '';
this.model1.treeInfoVO.forEach(it=>{//每次的新增品種都給title一份,用來搜索查詢
if(this.model1.title=='') {
this.model1.title += it.kind;
} else {
this.model1.title += ',' + it.kind;
}
})
sendApplication(this.model1).then(res=>{
if(res.code==200) {
this.isSubmit = true;
this.$refs.uToast.show({
type: 'success',
message: '提交成功',
duration: 1000,
complete() {
uni.removeStorageSync('cacheApplyInfo');
uni.setStorageSync('submitEvent',1);
uni.navigateBack({delta: 1});
}
});
}
})
}
}).catch(()=>{});
}
},
beforeDestroy() {
if(!this.isSubmit) {
uni.setStorageSync('cacheApplyInfo',JSON.stringify(this.model1));
}
},
onShow() {
/* 獲取省份列表 */
getAddress({addressType: 1}).then(res=>{
if(res.code==200) {
this.province = res.data;
res.data.forEach(item=>{
this.addressColumn[0].push(item.address);
})
}
})
this.model1.timeIn = new Date().getTime();
/* 獲取申請人備案信息 */
if(uni.getStorageSync('cacheApplyInfo')=="") {
getInformation().then(res=>{
if(res.code==200) {
let data = res.data;
if(data.perType==1) {
this.model1.name = data.name;
this.model1.address = data.addr;
this.model1.tel = data.tel;
} else if(data.perType==2) {
this.model1.name = data.businessName;
this.model1.address = data.addr;
this.model1.tel = data.tel;
}
}
})
} else {
this.model1 = JSON.parse(uni.getStorageSync('cacheApplyInfo'));
let d = new Date(this.model1.timeIn*1);
this.model1.timeIn = this.model1.timeIn*1;
this.model1.applyTime = d.getFullYear() +'年'+ (d.getMonth() + 1) +'月'+ d.getDate() +'日'+ d.getHours() +'時'+ d.getMinutes() +'分';
this.imgIds = this.model1.rid.split(',');
this.getImgs();
}
},
onReady() {
this.$refs.form1.setRules(this.rules1);// 如果需要兼容微信小程序,并且校驗規(guī)則中含有方法等,只能通過setRules方法設(shè)置規(guī)則。
this.$refs.form2.setRules(this.rules2);// 如果需要兼容微信小程序,并且校驗規(guī)則中含有方法等,只能通過setRules方法設(shè)置規(guī)則。
this.$refs.datetimePicker.setFormatter(this.formatter2);// 微信小程序需要用此寫法(時間格式化)
}
}
</script>
<style lang="scss" scoped>
.container {
/deep/.u-input {
padding-left: 0 !important;
}
/deep/.u-form-item__body__left__content__label,
/deep/.u-input__content__field-wrapper__field,
/deep/.u-textarea__field {
font-size: 13px !important;
}
.bg_gradient {
width: 100%;
height: 100px;
background-image: linear-gradient(to bottom,#00c39c,#F9F9F9);
position: fixed;
top: 0;
z-index: -1;
}
.applyInfo {
background-color: #fff;
border-radius: 8px;
margin: 16px 16px 0;
padding: 12px;
.applyTable {
.addProduct {
border: 1px solid #EAEBEC;margin: 5px 0; padding: 3px; color: #303133;
position: relative;
.deleteProduct {
width: 20px;
height: 20px;
line-height: 15px;
text-align: center;
font-size: 15px;
background-color: #373737;
color: #fff;
border-bottom-left-radius: 20px;
z-index: 3;
position: absolute;
right: 0;
top: 0;
}
.p {
margin: 0 0 3px 0;
display: flex;
view:nth-child(1) {
width: 70px;
}
view:nth-child(2) {
margin: 0 15px 0 3px;
width: calc(100% - 80px);
word-wrap: break-word;
}
}
}
}
.title {
margin: 10px 0 0 0;
}
.title,.photo {
.up {
font-size: 13px;
color: #666666;
display: flex;
b {
margin-right: 6px;
color: #f10000;
}
}
.down {
margin-top: 10px;
}
}
.submitBtn {
margin: 20px 0 0 0;
}
}
}
</style>
2.?水印相機(子組件)文章來源地址http://www.zghlxwxcb.cn/news/detail-773573.html
<template>
<view class="container">
<button @click="openCamera" :disabled="submitDisabled">水印相機</button>
<view class="myImgs">
<view class="screenImgs" v-for="(it,index) in imgSrcArr" :key="index">
<view class="deleteImg" @click="delImg(it)">x</view>
<u-album :urls="[it]"></u-album>
</view>
</view>
<canvas
canvas-id="myCanvasId"
:style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"
v-show="canvasShow"
></canvas>
</view>
</template>
<script>
export default {
props: {
imgUrls: {
type: Array,
default() {
return [];
}
},
submitDisabled: {
type: Boolean,
default: false,
}
},
data() {
return {
context: null, // canvas上下文
canvasWidth: 0, // canvas容器寬度
canvasHeight: 0, // canvas容器高度
canvasShow: true, // canvas容器是否存在
imgSrcArr: [], // 本地展示的圖片路徑(canvas容器圖片)
addressInfo: '', // 位置
longitude: '', // 經(jīng)度
latitude: '', // 緯度
imageInfo: '', // 拍照得到的照片信息
}
},
methods: {
/* 刪除照片 */
delImg(srcVal) {
this.$emit('deleteEvent',srcVal);
this.imgSrcArr = this.imgSrcArr.filter(item=>{
if(srcVal!=item) return item;
})
},
/* 點擊水印相機按鈕 */
async openCamera() {
this.$emit('cameraEvent');
if(this.imgSrcArr.length>7) {
uni.showToast({icon: 'none',duration: 2500,title: `最多上傳【8】張`});
this.$emit('cameraCloseEvent');
return;
}
try {
const res = await uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['camera'],
})
if(res[1]===undefined) {
this.$emit('cameraCloseEvent');
}
this.imageInfo = await uni.getImageInfo({
src: res[1].tempFilePaths[0],
})
const { width, height } = this.imageInfo[1];
// 計算canvas寬高,照片橫拍與豎拍的比例自適應(yīng)規(guī)則
const ratio = width / height;
const maxWidth = uni.upx2px(960); // 最大寬度為960rpx
const maxHeight = uni.upx2px(720);// 最大高度為720rpx
/**
* 規(guī)則:1.照片寬度大于最大寬度,以最大寬度為準(zhǔn)
* 規(guī)則:2.照片高度大于最大高度,以最大高度為準(zhǔn)
* 規(guī)則:3.照片高度或照片寬度任意一個超出最值范圍,以最大高度和寬度為準(zhǔn)
*/
if (width > maxWidth) {
this.canvasWidth = maxWidth;
this.canvasHeight = this.canvasWidth / ratio;
} else if (height > maxHeight) {
this.canvasHeight = maxHeight;
this.canvasWidth = this.canvasHeight * ratio;
} else {
this.canvasWidth = width;
this.canvasHeight = height;
}
this.locationInfo(); // 獲取定位信息
} catch (err) {}
},
/* 當(dāng)前定位信息 */
locationInfo() {
uni.getLocation({
type: 'gcj02',
success: res => {
this.latitude = res.latitude;
this.longitude = res.longitude;
this.placeInfo(); // 獲取位置信息
},
fail: () => {
uni.showToast({ icon: 'none', duration: 2500, title: `獲取位置信息失敗` });
},
})
},
/* 當(dāng)前位置信息 */
placeInfo() {
let getAddressUrl = `https://apis.map.qq.com/ws/geocoder/v1/?location=${this.latitude},${this.longitude}&key=你的key值`;
uni.$u.http.get(getAddressUrl).then(res=>{
this.addressInfo = res.result.address;
this.createCanvas(); // 創(chuàng)建canvas容器
})
},
/* canvas容器 */
createCanvas() {
this.context = uni.createCanvasContext('myCanvasId',this);
this.context.drawImage(this.imageInfo[1].path, 0, 0, this.canvasWidth, this.canvasHeight);
this.context.setFontSize(16);
this.context.setFillStyle('#ffffff');
this.context.fillText(this.currentTime(), 10, this.canvasHeight - 30);
this.context.fillText(`${this.addressInfo}`, 10, this.canvasHeight - 60);
this.context.fillText(`經(jīng)度: ${this.longitude}`, 10, this.canvasHeight - 90);
this.context.fillText(`緯度: ${this.latitude}`, 10, this.canvasHeight - 120);
this.canvasShow = false;
this.watermarkPhoto(); // 獲取水印照片
},
/* 水印照片 */
watermarkPhoto() {
let that = this;
this.context.draw(false, () => {
// 將canvas轉(zhuǎn)成圖片路徑
uni.canvasToTempFilePath({
canvasId: 'myCanvasId',
success: function(res) {
// 將圖片路徑賦值給image標(biāo)簽的src屬性
that.imgSrcArr.push(res.tempFilePath);
that.canvasShow = true;
that.canvasWidth = 0;
that.canvasHeight = 0;
that.$emit('finishEvent',res.tempFilePath);
}
},this);
});
},
/* 當(dāng)前日期時間 */
currentTime() {
let d = new Date();
// 年
let year = d.getFullYear();
// 月
let month = d.getMonth() + 1;
month = month > 9 ? month : '0'+month;
// 日
let date = d.getDate();
date = date > 9 ? date : '0'+date;
// 時
let hours = d.getHours();
hours = hours > 9 ? hours : '0'+hours;
// 分
let minutes = d.getMinutes();
minutes = minutes > 9 ? minutes : '0'+minutes;
// 秒
let seconds = d.getSeconds();
seconds = seconds > 9 ? seconds : '0'+seconds;
// 星期
let weekdayArr = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'];
let weekday = weekdayArr[d.getDay()];
return year+"-"+month+"-"+date+" "+hours+":"+minutes+":"+seconds+" "+weekday;
},
},
watch: {
imgUrls: {
deep: true,
handler() {
this.imgSrcArr = [...this.imgUrls];
}
}
}
}
</script>
<style lang="scss" scoped>
/deep/[role=img] {
width: 80px !important;
height: 80px !important;
}
.container {
.myImgs {
margin: 10px 0 0 0;
display: flex;
flex-wrap: wrap;
.screenImgs {
margin: 0 4px 4px 0;
position: relative;
.deleteImg {
width: 20px;
height: 20px;
line-height: 15px;
text-align: center;
font-size: 15px;
background-color: #373737;
color: #fff;
border-bottom-left-radius: 20px;
z-index: 3;
position: absolute;
right: 0;
top: 0;
}
}
}
}
</style>
到了這里,關(guān)于uniapp水印相機(水印照片,圖片加水印)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!