uniapp 微信小程序自定义相机实现ocr识别、拍摄图片增加取景框功能

1. 效果

      

2. 完整代码
<template>
	<view :style="{ height: windowHeight + 'px' }">
		<!-- 相机区域 -->
		<camera mode="normal" :device-position="devicePosition" :flash="flashStyle" :style="{ height: cameraHeight + 'px' }" @error="errorCamera">
			<cover-view class="controls" style="width: 100%; height: 100%">
				<cover-view class="controls1-bgcolor"></cover-view>
				<cover-view class="camera-bgcolor">
					<cover-view class="center-top"></cover-view>
					<cover-view class="center" id="myCamera">
						<!-- 身份证正面 -->
						<cover-image v-if="photoType == 'idCardCopy'" class="cover_img" src="../../static/images/sfzz.png" mode="widthFix" />
						<!-- 身份证反面 -->
						<cover-image v-else-if="photoType == 'idCardNational'" class="cover_img" src="../../static/images/sfzf.png" mode="widthFix" />
						<!-- 银行卡正面或反面 -->
						<cover-image
							v-else-if="photoType == 'bankCardPicFront' || photoType == 'bankCardPicBack'"
							class="cover_img"
							src="../../static/images/bank.png"
							mode="widthFix"
						/>
					</cover-view>
					<cover-view class="center-bottom"></cover-view>
				</cover-view>
				<cover-view class="controls3-bgcolor"></cover-view>
			</cover-view>
		</camera>

		<!-- 底部操作区域 -->
		<view class="bottom bottom-box">
			<view class="wrap">
				<!-- 相册 -->
				<view @click="chooseImage">
					<image :src="picture" mode="" style="width: 60rpx; height: 60rpx"></image>
				</view>
				<!-- 相机 -->
				<view @click="takePhoto">
					<image class="take-box" :src="icon"></image>
				</view>
				<!-- 切换前后摄像头 -->
				<view class="back" @click="switchBtn">
					<image :src="flip" mode="" style="width: 60rpx; height: 60rpx"></image>
				</view>
			</view>
		</view>

		<canvas class="cop" canvas-id="image-canvas"></canvas>
	</view>
</template>

<script>
export default {
	data() {
		return {
			flip: '../../static/images/fz.png', // 反转
			icon: '../../static/images/pho.png', // 相机
			picture: '../../static/images/xc.png', // 照片
			cameraContext: {},
			windowHeight: '',
			cameraHeight: '',
			idcardFrontSide: true,
			photoType: '',
			devicePosition: 'back', // 摄像头默认后置
			flashStyle: 'off',
			tokens: ''
		};
	},
	onLoad(options) {
		if (uni.createCameraContext) {
			this.cameraContext = uni.createCameraContext();
		} else {
			// 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
			uni.showModal({
				title: '提示',
				content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
			});
		}
		this.photoType = options.photoType;
		this.devicePosition = 'back';
		this.tokens = uni.getStorageSync('usertoken');
	},
	onShow() {
		const systemInfo = uni.getSystemInfoSync();
		this.windowHeight = systemInfo.windowHeight;
		this.cameraHeight = systemInfo.windowHeight - 160;
	},
	methods: {
		errorCamera(e) {
			const that = this;
			uni.getSetting({
				success(res) {
					if (!res.authSetting['scope.camera']) {
						uni.showModal({
							title: '提示',
							content: '请开启摄像头权限,否则无法拍照',
							confirmText: '去开启',
							success(res) {
								if (res.confirm) {
									uni.openSetting({
										success(res) {
											if (res.authSetting['scope.camera']) {
												uni.navigateBack({
													delta: 1
												});
											} else {
												uni.navigateBack({
													delta: 1
												});
											}
										}
									});
								} else if (res.cancel) {
									uni.navigateBack({
										delta: 1
									});
								}
							}
						});
					}
				}
			});
		},
		// 拍照
		takePhoto() {
			uni.showLoading({
				title: '拍摄中'
			});
			this.cameraContext.takePhoto({
				quality: 'normal',
				success: (res) => {
					console.log('拍摄照片', res);
					let idPhoto = res.tempImagePath;
					this.loadTempImagePath(idPhoto);
					uni.showToast({
						title: '拍照成功',
						icon: 'none',
						duration: 1200
					});
				},
				fail: (err) => {
					uni.showToast({
						title: '拍照失败,请检查系统是否授权',
						icon: 'none',
						duration: 1200
					});
				}
			});
		},

		//rpx转px
		rpx2px(rpx) {
			const screenWidth = uni.getSystemInfoSync().screenWidth;
			return (screenWidth * Number.parseInt(rpx)) / 750;
		},

		loadTempImagePath(url) {
			let { windowWidth, windowHeight } = uni.getSystemInfoSync();

			const camera = uni.createSelectorQuery().select('#myCamera'); // 获取camera组件
			camera
				.boundingClientRect((data) => {
					const x = data.left; // 取景框左上角的x坐标
					const y = data.top; // 取景框左上角的y坐标
					const width = data.width; // 取景框的宽度
					const height = data.height + 120; // 取景框的高度
					console.log(x, y, width, height, 'x, y, width, height');
					let testc = uni.createCanvasContext('image-canvas');
					testc.drawImage(url, 0, 0, windowWidth, windowHeight);
					testc.draw(false, () => {
						uni.canvasToTempFilePath({
							x: x, //设置图片x轴起始点
							y: y, //设置图片y轴起始点
							width: width,
							height: height,
							canvasId: 'image-canvas',
							fileType: 'jpg',
							quality: 1,
							complete: (res2) => {
								console.log(res2.tempFilePath, 'res2.tempFilePath88');
								this.chosePhoto(res2.tempFilePath);
							}
						});
					});
				})
				.exec();
		},

		// 从相册选取
		chooseImage() {
			uni.chooseImage({
				count: 1,
				sizeType: ['original', 'compressed'],
				sourceType: ['album'],
				success: (res) => {
					let idPhoto = res.tempFilePaths[0];
					this.chosePhoto(idPhoto);
				},
				fail: (err) => {}
			});
		},

		//反转
		switchBtn() {
			if (this.devicePosition == 'front') {
				this.devicePosition = 'back';
			} else {
				this.devicePosition = 'front';
			}
		},

		// 选择图片跳转
		chosePhoto(item) {
			console.log(item, this.photoType, '拍摄完成');
			if (this.photoType == 'idCardCopy' || this.photoType == 'bankCardPicFront') {
				// 身份证正面 银行卡正面
				this.ocrCard(item);
			} else if (this.photoType == 'idCardNational' || this.photoType == 'bankCardPicBack') {
				// 身份证反面 银行卡反面
				this.uploadCard(item);
			}
		},

		// 身份证正面/银行卡 ocr识别
		ocrCard(item) {
			uni.uploadFile({
				url: this.photoType == 'idCardCopy' ? getApp().globalData.globalOcrCardUrl : getApp().globalData.globalOcrBankUrl,
				filePath: item,
				header: {
					'Blade-Auth': 'bearer ' + this.tokens,
					'Tenant-Id': '000000',
					'Blade-Requested-With': 'BladeHttpRequest'
				},
				name: 'file',
				complete: (res) => {
					console.log('res', JSON.parse(res.data));
					let link = JSON.parse(res.data);
					if (link.code == 200) {
						if (this.photoType == 'idCardCopy') {
							uni.$emit('onOcrCard', link);
						} else {
							uni.$emit('onOcrBank', link);
						}
						uni.navigateBack({
							delta: 1
						});
					} else {
						uni.showToast({
							title: link.msg,
							icon: 'none'
						});
					}
				}
			});
		},

		//  身份证反面/银行卡反面上传
		uploadCard(item) {
			uni.uploadFile({
				url: getApp().globalData.uploadUrl,
				filePath: item,
				name: 'file',
				header: {
					'Blade-Auth': 'bearer ' + this.tokens,
					'Tenant-Id': '000000',
					'Blade-Requested-With': 'BladeHttpRequest'
				},
				success: (res) => {
					let data = JSON.parse(res.data);
					if (this.photoType == 'idCardNational') {
						uni.$emit('onCard', data);
					} else {
						uni.$emit('onBank', data);
					}
					uni.navigateBack({
						delta: 1
					});
				}
			});
		}
	}
};
</script>

<style lang="scss" scoped>
.top-box {
	height: 200rpx;
	background-color: #000;
}
.camera-box {
	display: flex;
	align-items: center;
	justify-content: center;
	// flex-direction: column;
}

.camera-con {
	width: 520rpx;
	height: 100%;
}

.camera-bgcolor {
	// width: 66%;
	width: 520rpx;
	height: 100%;
}
.center {
	width: 100%;
	height: 750rpx;
	display: flex;
	align-items: center;
	justify-content: center;
}
.center-top {
	width: 100%;
	height: calc((100% - 750rpx) / 2);
	background-color: rgba(248, 248, 248, 0.6);
}

.center-bottom {
	width: 100%;
	height: calc((100% - 750rpx) / 2);
	background-color: rgba(248, 248, 248, 0.6);
}


.bottom {
	width: 100%;
	background-color: #000;
}

.wrap {
	display: flex;
	align-items: center;
	justify-content: space-between;
	height: 320rpx;
	padding: 0 73rpx;
}

.take-box {
	width: 131rpx;
	height: 131rpx;
}

.bottom-box {
	font-size: 36rpx;
	color: #fff;
}

.controls {
	display: flex;
	align-items: center;
	justify-content: center;
	// flex-direction: column;
}

.controls1-bgcolor {
	list-style: none;
	padding: 0;
	margin: 0;
	// width: 22%;
	width: calc((100% - 522rpx) / 2);
	height: 100%;
	background-color: rgba(248, 248, 248, 0.6);
}

.camera-bgcolor {
	// width: 66%;
	width: 520rpx;
	height: 100%;
}
.center {
	width: 100%;
	height: 750rpx;
	display: flex;
	align-items: center;
	justify-content: center;
}
.center-top {
	width: 100%;
	height: calc((100% - 750rpx) / 2);
	background-color: rgba(248, 248, 248, 0.6);
}

.center-bottom {
	width: 100%;
	height: calc((100% - 750rpx) / 2);
	background-color: rgba(248, 248, 248, 0.6);
}

.cover_img {
	width: 520rpx;
}

.controls3-bgcolor {
	list-style: none;
	padding: 0;
	margin: 0;
	width: calc((100% - 520rpx) / 2);
	height: 100%;
	background-color: rgba(248, 248, 248, 0.6);
}

.cop {
	width: 100%;
	height: 100vh;
}
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于uniapp微信小程序,你可以通过自定义组件来实现自定义tabbar。以下是一种实现方法: 1. 在 uniapp 项目中创建一个新的自定义组件,例如 "custom-tabbar"。 2. 在 custom-tabbar 组件的文件夹中,创建一个 JSON 文件,命名为 "custom-tabbar.json"。在该文件中定义组件使用的自定义属性,例如: ```json { "component": true, "usingComponents": {} } ``` 3. 在 custom-tabbar 组件的文件夹中,创建一个 WXML 文件,命名为 "custom-tabbar.wxml"。在该文件中编写自定义tabbar的布局,例如: ```html <view class="custom-tabbar"> <!-- 自定义的tabbar按钮 --> <view class="custom-tabbar-item" bindtap="navigateToPage"> <!-- 按钮图标 --> <image src="{{ activeIndex === 0 ? 'icon1-active' : 'icon1' }}"></image> <!-- 按钮文字 --> <text class="{{ activeIndex === 0 ? 'active' : '' }}">Tab1</text> </view> <view class="custom-tabbar-item" bindtap="navigateToPage"> <!-- 按钮图标 --> <image src="{{ activeIndex === 1 ? 'icon2-active' : 'icon2' }}"></image> <!-- 按钮文字 --> <text class="{{ activeIndex === 1 ? 'active' : '' }}">Tab2</text> </view> <!-- 更多按钮 --> <view class="custom-tabbar-item more" bindtap="showMoreOptions"> <!-- 更多按钮图标 --> <image src="more-icon"></image> </view> </view> ``` 4. 在 custom-tabbar 组件的文件夹中,创建一个 WXSS 文件,命名为 "custom-tabbar.wxss"。在该文件中编写自定义tabbar的样式,例如: ```css .custom-tabbar { display: flex; align-items: center; height: 50px; background-color: #fff; } .custom-tabbar-item { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; } .custom-tabbar-item image { width: 30px; height: 30px; } .custom-tabbar-item text { font-size: 12px; margin-top: 5px; } .custom-tabbar-item.more { position: relative; } .custom-tabbar-item.more image { width: 40px; height: 40px; } .active { color: #007aff; } ``` 5. 在需要使用自定义tabbar的页面中,引入 custom-tabbar 组件,例如: ```html <template> <view> <!-- 页面内容 --> </view> <!-- 引入自定义tabbar组件 --> <custom-tabbar></custom-tabbar> </template> <script> import customTabbar from '@/components/custom-tabbar/custom-tabbar' export default { components: { customTabbar }, // 页面逻辑代码 } </script> <style> /* 页面样式 */ </style> ``` 通过以上步骤,你就可以在uniapp微信小程序实现自定义tabbar了。你可以根据自己的需求修改自定义tabbar的布局和样式,以及处理相应的点击事件。希望能对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值