欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

uniapp實現(xiàn)人臉識別功能的具體實現(xiàn)代碼

 更新時間:2022年12月05日 10:29:03   作者:邊中之城  
最近在使用uniapp開發(fā)項目,有刷臉實名認證的需求,下面這篇文章主要給大家介紹了關(guān)于uniapp實現(xiàn)人臉識別功能的具體實現(xiàn),文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下

前言

對于前端來說,需要后端提供一個人臉識別接口,前端傳入圖片,接口識別并返回結(jié)果,如此看來,其實前端只需實現(xiàn)圖片傳入即可,但是其實不然,在傳入圖片時,需要進行以下幾點操作:

  • 判斷圖片格式,市場上比較常見的是.jpg、.jpeg、.png
  • 計算文件大小,一般要求不超過5MB
  • 對圖片進行base64加密

其實前2點具體要看接口要求,但是第3點,是實現(xiàn)人臉識別必備步驟,下文重點講述一下移動端實現(xiàn)人臉識別的base64加密方法

問題

項目主要使用的技術(shù)棧是uniapp,uniapp的優(yōu)點是上手快,基于vue開發(fā),但缺點也很明顯,多環(huán)境兼容導(dǎo)致兼容性較差,真機調(diào)試和運行較慢。比如h5端可以輕松實現(xiàn)base64加密,但是安卓環(huán)境完全不行,因為本地上傳圖片時,會返回一個blob流,但是uniapp的blob流是以<http://localhost>…(安卓環(huán)境無法識別localhost)開始,導(dǎo)致無法進行base64加密

解決辦法

經(jīng)過多方實現(xiàn)后,借用html5+ api的多個結(jié)合方法(plus.zip.compressImage、plus.io.resolveLocalFileSystemURL、plus.io.FileReader)實現(xiàn)加密,主要代碼如下:

//app壓縮圖片  用for循環(huán) 來處理圖片壓縮 的問題,原因是 plus.zip.compressImage 方法 是異步執(zhí)行的,for循環(huán)很快, 同時手機可執(zhí)行的壓縮方法有限制:應(yīng)該是3個吧。超出直接就不執(zhí)行了。所以 原理就是 在圖片壓縮成功后 繼續(xù) 回調(diào) 壓縮函數(shù)。 以到達循環(huán)壓縮圖片的功能。
app_img(num, rem) {
  let that = this;
  let index = rem.tempFiles[num].path.lastIndexOf('.'); //獲取圖片地址最后一個點的位置
  let img_type = rem.tempFiles[num].path.substring(index + 1, rem.tempFiles[num].path.length); //截取圖片類型如png jpg
  let img_yuanshi = rem.tempFiles[num].path.substring(0, index); //截取圖片原始路徑
  let d2 = new Date().getTime(); //時間戳
  //壓縮圖片
  plus.zip.compressImage(
    {
      src: rem.tempFiles[num].path, //你要壓縮的圖片地址
      dst: img_yuanshi + d2 + '.' + img_type, //壓縮之后的圖片地址(注意壓縮之后的路徑最好和原生路徑的位置一樣,不然真機上報code-5)
      quality: 70 //[10-100]
    },
    function (e) {
      //壓縮之后路徑轉(zhuǎn)base64位的
      //通過URL參數(shù)獲取目錄對象或文件對象
      plus.io.resolveLocalFileSystemURL(e.target, function (entry) {
        // 可通過entry對象操作test.html文件
        entry.file(function (file) {
          //獲取文件數(shù)據(jù)對象
          var fileReader = new plus.io.FileReader(); // 文件系統(tǒng)中的讀取文件對象,用于獲取文件的內(nèi)容
          //alert("getFile:" + JSON.stringify(file));
          fileReader.readAsDataURL(file); //以URL編碼格式讀取文件數(shù)據(jù)內(nèi)容
          fileReader.onloadend = function (evt) {
            //讀取文件成功完成的回調(diào)函數(shù)
            that.base64Img = evt.target.result.split(',')[1]; //拿到‘data:image/jpeg;base64,‘后面的
            console.log('that.base64Img', that.base64Img);
            // rem.tempFiles[num].Base64_Path = evt.target.result.split(',')[1];
          };
        });
      });
      // that.base64Img = that.base64Img.concat(rem.tempFiles[num]);
      // 【注意】在此人臉認證中,只會傳一張圖片,故不考慮多張圖片情況
      //利用遞歸循環(huán)來實現(xiàn)多張圖片壓縮
      // if (num == rem.tempFiles.length - 1) {
      // 	return;
      // } else {
      // 	that.app_img(num + 1, rem);
      // }
    },
    function (error) {
      console.log('Compress error!');
      console.log(JSON.stringify(error));
      uni.showToast({
        title: '編碼失敗' + error
      });
    }
  );
},

詳細實現(xiàn)思路

其實對于uniapp實現(xiàn)人臉識別功能來講,大概要經(jīng)過這么幾個步驟

  • onImage():打開手機相冊上傳圖片,獲取blob流(本地臨時地址)
  • #ifdef APP-PLUS/#ifndef APP-PLUS:判斷系統(tǒng)環(huán)境,是h5還是安卓環(huán)境,然后在進行圖片壓縮和加密,具體實現(xiàn)代碼如下:
//#ifdef APP-PLUS
//圖片壓縮
that.app_img(0, res);
//#endif

// #ifndef APP-PLUS
that.blobTobase64(res.tempFilePaths[0]);
// #endif
  • app_img()/blobTobase64():對要識別的圖片進行base64加密
  • onSave()—>upImage():附件上傳,并處理識別信息

具體代碼

<!-- 人臉認證 -->
<template>
	<view>
		<view class="u-margin-30 text-center"><u-avatar size="600" :src="imageSrc"></u-avatar></view>
		<view class="u-margin-60">
			<u-button type="primary" class="u-margin-top-60" @click="onImage">{{ !imageSrc ? '拍照' : '重拍' }}</u-button>
			<!-- <u-button type="primary" class="u-margin-top-30">重拍</u-button> -->
			<u-button type="primary" class="u-margin-top-50" @click="onSave">保存</u-button>
		</view>
		<u-toast ref="uToast" />
	</view>
</template>

<script>
import { registerOrUpdateFaceInfo, UpdateLaborPersonnel } from '@/api/mww/labor.js';
import { UploadByProject } from '@/api/sys/upload.js';
import { sysConfig } from '@/config/config.js';
import storage from 'store';
import { ACCESS_TOKEN } from '@/store/mutation-types';
export default {
	name: 'face-authentication',
	data() {
		return {
			imageSrc: '',
			lastData: {},
			base64Img: '',
			base64: ''
		};
	},
	onLoad(option) {
		this.lastData = JSON.parse(decodeURIComponent(option.lastData));
		console.log('前一個頁面數(shù)據(jù)', this.lastData);
		uni.setNavigationBarTitle({
			title: this.lastData.CnName + '-人臉認證 '
		});
	},
	methods: {
		onSave() {
			if (!this.imageSrc) {
				this.$refs.uToast.show({
					title: '請先拍照',
					type: 'error'
				});
			}
			// 人臉上傳,附件上傳,勞務(wù)人員信息修改
			this.upImage();
		},
		// h5壓縮圖片的方式,url為圖片流
		blobTobase64(url) {
			console.log('進來了2', url);
			let imgFile = url;
			let _this = this;
			uni.request({
				url: url,
				method: 'GET',
				responseType: 'arraybuffer',
				success: res => {
					let base64 = uni.arrayBufferToBase64(res.data); //把arraybuffer轉(zhuǎn)成base64
					_this.base64Img = 'data:image/jpeg;base64,' + base64; //不加上這串字符,在頁面無法顯示
				}
			});
		},
		//app壓縮圖片  用for循環(huán) 來處理圖片壓縮 的問題,原因是 plus.zip.compressImage 方法 是異步執(zhí)行的,for循環(huán)很快, 同時手機可執(zhí)行的壓縮方法有限制:應(yīng)該是3個吧。超出直接就不執(zhí)行了。所以 原理就是 在圖片壓縮成功后 繼續(xù) 回調(diào) 壓縮函數(shù)。 以到達循環(huán)壓縮圖片的功能。
		app_img(num, rem) {
			let that = this;
			let index = rem.tempFiles[num].path.lastIndexOf('.'); //獲取圖片地址最后一個點的位置
			let img_type = rem.tempFiles[num].path.substring(index + 1, rem.tempFiles[num].path.length); //截取圖片類型如png jpg
			let img_yuanshi = rem.tempFiles[num].path.substring(0, index); //截取圖片原始路徑
			let d2 = new Date().getTime(); //時間戳
			//壓縮圖片
			plus.zip.compressImage(
				{
					src: rem.tempFiles[num].path, //你要壓縮的圖片地址
					dst: img_yuanshi + d2 + '.' + img_type, //壓縮之后的圖片地址(注意壓縮之后的路徑最好和原生路徑的位置一樣,不然真機上報code-5)
					quality: 70 //[10-100]
				},
				function(e) {
					//壓縮之后路徑轉(zhuǎn)base64位的
					//通過URL參數(shù)獲取目錄對象或文件對象
					plus.io.resolveLocalFileSystemURL(e.target, function(entry) {
						// 可通過entry對象操作test.html文件
						entry.file(function(file) {
							//獲取文件數(shù)據(jù)對象
							var fileReader = new plus.io.FileReader(); // 文件系統(tǒng)中的讀取文件對象,用于獲取文件的內(nèi)容
							//alert("getFile:" + JSON.stringify(file));
							fileReader.readAsDataURL(file); //以URL編碼格式讀取文件數(shù)據(jù)內(nèi)容
							fileReader.onloadend = function(evt) {
								//讀取文件成功完成的回調(diào)函數(shù)
								that.base64Img = evt.target.result.split(',')[1]; //拿到‘data:image/jpeg;base64,‘后面的
								console.log('that.base64Img', that.base64Img);
								// rem.tempFiles[num].Base64_Path = evt.target.result.split(',')[1];
							};
						});
					});
					// that.base64Img = that.base64Img.concat(rem.tempFiles[num]);
					// 【注意】在此人臉認證中,只會傳一張圖片,故不考慮多張圖片情況
					//利用遞歸循環(huán)來實現(xiàn)多張圖片壓縮
					// if (num == rem.tempFiles.length - 1) {
					// 	return;
					// } else {
					// 	that.app_img(num + 1, rem);
					// }
				},
				function(error) {
					console.log('Compress error!');
					console.log(JSON.stringify(error));
					uni.showToast({
						title: '編碼失敗' + error
					});
				}
			);
		},
		// 打開手機相機相冊功能
		onImage() {
			const that = this;
			// 安卓系統(tǒng)無法默認打開前置攝像頭,具體請看下面app-plus原因,
			uni.chooseImage({
				count: 1, //默認9
				sizeType: ['original', 'compressed'], //可以指定是原圖還是壓縮圖,默認二者都有
				sourceType: ['camera'], // 打開攝像頭-'camera',從相冊選擇-'album'
				success: function(res) {
					console.log('文件結(jié)果', res);
					if (res.tempFilePaths.length > 0) {
						// Blob流地址
						that.imageSrc = res.tempFilePaths[0];
						//#ifdef APP-PLUS
						//圖片壓縮
						that.app_img(0, res);
						//#endif
						// #ifndef APP-PLUS
						that.blobTobase64(res.tempFilePaths[0]);
						// #endif
					} else {
						that.$refs.uToast.show({
							title: '無文件信息',
							type: 'error'
						});
					}
				},
				fail: function(res) {
					console.log('失敗了', res.errMsg);
					that.$refs.uToast.show({
						title: res.errMsg,
						type: 'error'
					});
				}
			});
			// #ifdef APP-PLUS
			// console.log('app環(huán)境了');
			// 指定要獲取攝像頭的索引值,1表示主攝像頭,2表示輔攝像頭。如果沒有設(shè)置則使用系統(tǒng)默認主攝像頭。
			// 平臺支持【注意注意注意】
			// Android - 2.2+ (不支持) :
			// 暫不支持設(shè)置默認使用的攝像頭,忽略此屬性值。打開拍攝界面后可操作切換。
			// iOS - 4.3+ (支持)
			// var cmr = plus.camera.getCamera(1);
			// var res = cmr.supportedImageResolutions[0];
			// var fmt = cmr.supportedImageFormats[0];
			// console.log('Resolution: ' + res + ', Format: ' + fmt);
			// cmr.captureImage(
			// 	function(path) {
			// 		alert('Capture image success: ' + path);
			// 	},
			// 	function(error) {
			// 		alert('Capture image failed: ' + error.message);
			// 	},
			// 	{ resolution: res, format: fmt }
			// );
			// #endif
		},
		// 上傳附件至[人臉認證]服務(wù)器
		upImage() {
			if (!this.base64Img) {
				this.$refs.uToast.show({
					title: '無圖片信息',
					type: 'error'
				});
				return;
			}
			const params = {
				identityId: this.lastData.IdCard, //身份證號碼
				imgInfo: this.base64Img, //頭像采用base64編碼
				userId: this.lastData.Id, //勞務(wù)人員Id
				userName: this.lastData.CnName //勞務(wù)姓名
			};
			uni.showLoading();
			registerOrUpdateFaceInfo(params)
				.then(res => {
					if (res.success) {
						this.$refs.uToast.show({
							title: '認證成功',
							type: 'success'
						});
						// 上傳至附件服務(wù)器+修改勞務(wù)人員信息
						this.uploadFile();
					} else {
						this.$refs.uToast.show({
							title: '認證失敗,' + res.message,
							type: 'error'
						});
						uni.hideLoading();
					}
				})
				.catch(err => {
					uni.hideLoading();
					uni.showModal({
						title: '提示',
						content: err
					});
				});
		},
		// 上傳附件至附件服務(wù)器
		uploadFile() {
			const obj = {
				project: this.lastData.OrgCode || this.$store.getters.projectCode.value,
				module: 'mww.personnelCertification',
				segment: this.lastData.OrgCode,
				businessID: this.lastData.Id,
				storageType: 1
			};
			let str = `project=${obj.project}&module=${obj.module}&segment=${obj.segment}&businessID=${obj.businessID}&storageType=${obj.storageType}`;
			console.log('str', str);
			// const url = '';
			// console.log('url', url);
			// const formData = new FormData();
			// formData.append('file', this.imageSrc, '.png');
			// UploadByProject(str, formData).then(res => {
			// 	if (res.success) {
			// 		this.$refs.uToast.show({
			// 			title: '上傳成功',
			// 			type: 'success'
			// 		});
			// 	} else {
			// 		this.$refs.uToast.show({
			// 			title: res.message,
			// 			type: 'error'
			// 		});
			// 	}
			// });
			const token = uni.getStorageSync(ACCESS_TOKEN);
			const that = this;
			// 需要使用uniapp提供的api,因為that.imageSrc的blob流為地址頭為localhost(本地臨時文件)
			uni.uploadFile({
				url: `${sysConfig().fileServer}/UploadFile/UploadByProject?${str}`,
				filePath: that.imageSrc,
				formData: {
					...obj
				},
				header: {
					// 必須傳token,不然會報[系統(tǒng)標識不能為空]
					authorization: `Bearer ${token}`
				},
				name: 'file',
				success: res => {
					that.$refs.uToast.show({
						title: '上傳成功',
						type: 'success'
					});
					that.lastData.CertificationUrl = res.data[0].virtualPath;
					that.lastData.Certification = 1;
					that.updateLaborPersonnel();
				},
				fail: err => {
					console.log('上傳失敗了', err);
					that.$refs.uToast.show({
						title: '上傳失敗,' + err,
						type: 'error'
					});
					uni.hideLoading();
				}
			});
		},
		// 修改勞務(wù)人員信息
		updateLaborPersonnel() {
			UpdateLaborPersonnel(this.lastData)
				.then(res => {
					if (res.success) {
						this.$refs.uToast.show({
							title: '修改成功',
							type: 'success'
						});
						// uni.showToast({
						// 	title: '成功了'
						// });
						setTimeout(() => {
							uni.navigateBack({
								delta: 1
							});
						}, 800);
					} else {
						this.$refs.uToast.show({
							title: '修改失敗,' + res.message,
							type: 'error'
						});
					}
				})
				.finally(() => {
					uni.hideLoading();
				});
		}
	}
};
</script>

<style scoped lang="less"></style>

總結(jié)

到此這篇關(guān)于uniapp實現(xiàn)人臉識別功能的文章就介紹到這了,更多相關(guān)uniapp人臉識別功能內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論