uniapp实现自定义相机

起因

由于最近用uniapp调用原生相机容易出现闪退问题,找了很多教程又是压缩图片又是优化代码,我表示并没有太大作用!!

于是开启了我的解决之路

  • 利用livePusher实现

实现自定义相机

拓展性挺强的,可以实现自定义水印、身份证拍摄、人像拍摄等
这里我简单实现一个相机功能主要用于解决闪退

Tip:这里需要创建nvue文件哦~

创建camera.nvue

<template>
	<view class="pengke-camera" :style="{ width: windowWidth, height: windowHeight }">
		<live-pusher
			id="livePusher"
			ref="livePusher"
			class="livePusher"
			mode="FHD"
			beauty="0"
			whiteness="0"
			:aspect="aspect"
			min-bitrate="1000"
			audio-quality="16KHz"
			device-position="back"
			:auto-focus="true"
			:muted="true"
			:enable-camera="true"
			:enable-mic="false"
			:zoom="false"
			@statechange="statechange"
			:style="{ width: windowWidth, height: windowHeight }"
		></live-pusher>

		<view class="menu">
			<!--底部菜单区域背景-->
			<cover-image class="menu-mask" src="/static/live-camera/bar.png"></cover-image>

			<!--返回键-->
			<cover-image class="menu-back" @tap="back" src="/static/live-camera/back.png"></cover-image>

			<!--快门键-->
			<cover-image class="menu-snapshot" @tap="snapshot" src="/static/live-camera/shutter.png"></cover-image>

			<!--反转键-->
			<cover-image class="menu-flip" @tap="flip" src="/static/live-camera/flip.png"></cover-image>
		</view>
	</view>
</template>

<script>
let _this = null;
export default {
	data() {
		return {
			poenCarmeInterval:null,//打开相机的轮询
			aspect: '2:3', //比例
			windowWidth: '', //屏幕可用宽度
			windowHeight: '', //屏幕可用高度
			camerastate: false, //相机准备好了
			livePusher: null, //流视频对象
			snapshotsrc: null, //快照
		};
	},
	onLoad(e) {
		_this = this;
		this.initCamera();
	},
	onReady() {
		this.livePusher = uni.createLivePusherContext('livePusher', this);
		this.startPreview(); //开启预览并设置摄像头
		this.poenCarme();
	},
	methods: {
		
		//轮询打开
		poenCarme(){
			//#ifdef APP-PLUS
			if (plus.os.name == 'Android') {
				this.poenCarmeInterval = setInterval(function() {
					console.log(_this.camerastate);
					if (!_this.camerastate) _this.startPreview();
				}, 2500);
			}
			//#endif
		},
		//初始化相机
		initCamera() {
			uni.getSystemInfo({
				success: function(res) {
					_this.windowWidth = res.windowWidth;
					_this.windowHeight = res.windowHeight;
					let zcs = _this.aliquot(_this.windowWidth,_this.windowHeight);
					_this.aspect = (_this.windowWidth/zcs)+':'+(_this.windowHeight/zcs);
					// console.log('画面比例:'+_this.aspect);
				}
			});
		},
		
		//整除数计算
		aliquot(x, y) {
			if (x % y == 0) return y;
			return this.aliquot(y, x % y);
		},

		//开始预览
		startPreview() {
			this.livePusher.startPreview({
				success: a => {
					console.log(a)
				}
			});
		},
		
		//停止预览
		stopPreview() {
			this.livePusher.stopPreview({
				success: a => {
					_this.camerastate = false;
				}
			});
		},
		
		//状态
		statechange(e) {
			//状态改变
			console.log(e);
			if (e.detail.code == 1007) {
				_this.camerastate = true;
			} else if (e.detail.code == -1301) {
				_this.camerastate = false;
			}
		},
		

		//返回
		back() {
			uni.navigateBack();
		},

		//抓拍
		snapshot() {
			//震动
			uni.vibrateShort({
			    success: function () {
			        console.log('success');
			    }
			});
			//拍照
			this.livePusher.snapshot({
				success: e => {
					_this.snapshotsrc = e.message.tempImagePath;
					_this.stopPreview();
					_this.setImage();
					uni.navigateBack();
				}
			});
		},

		//反转
		flip() {
			this.livePusher.switchCamera();
		},

		//设置
		setImage() {
			let pages = getCurrentPages();
			let prevPage = pages[pages.length - 2];
			prevPage.$vm.setImage({ path: _this.snapshotsrc});
		}
	}
};
</script>

<style lang="less">
.pengke-camera {
	justify-content: center;
	align-items: center;
	.menu {
		position: absolute;
		left: 0;
		bottom: 0;
		width: 750rpx;
		height: 180rpx;
		z-index: 98;
		align-items: center;
		justify-content: center;
		.menu-mask {
			position: absolute;
			left: 0;
			bottom: 0;
			width: 750rpx;
			height: 180rpx;
			z-index: 98;
		}
		.menu-back {
			position: absolute;
			left: 30rpx;
			bottom: 50rpx;
			width: 80rpx;
			height: 80rpx;
			z-index: 99;
			align-items: center;
			justify-content: center;
		}
		.menu-snapshot {
			width: 130rpx;
			height: 130rpx;
			z-index: 99;
		}
		.menu-flip {
			position: absolute;
			right: 30rpx;
			bottom: 50rpx;
			width: 80rpx;
			height: 80rpx;
			z-index: 99;
			align-items: center;
			justify-content: center;
		}
	}
}
</style>

这里用了一些图片作为图标布局画面美观,例如返回图标,拍摄图标

使用

在点击拍照的时候跳转到camera页面即可
在需要使用的页面中编写setImage方法,即可拿到返回过来的图片临时路径
再通过uniapp自带的上传图片api进行上传至服务器即可
这样就避免了调用原生相机

setImage(e){
//e.path即是图片临时路径
uni.uploadFile({
	url: '上传接口的路径',
	filePath: e.path,
	name: 'imageFile',
	success: function(res) {
		//服务器返回的图片地址url
	},
	error: function(err) {
		console.log(err)
	}
}

效果图

在这里插入图片描述

拓展

如果既要实现从相册选又要手机拍呢?该如何实现
这里相册选调用的uniapp的api,
手机拍跳转到自定义相机页面即可

这里可以写一个弹窗,让它选择,如果选择了从相册选图片则

uni.chooseImage({
	count: size, //默认9
	sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
	sourceType: ['album'], //从相册选择
	success: function (res) {
		console.log(res)//拿到临时路径再向后端发送上传请求....
	}
});

如果用相机拍则跟上方步骤一致

实现多种自定义相机

这里的话我贴上效果图,如果需要就在我的博客资源中获取吧

水印相机

在这里插入图片描述

身份证相机

在这里插入图片描述

人像相机

在这里插入图片描述
这样我就成功解决了闪退问题~,有问题评论区d我

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
本课程讲了Vue3+Vue2+Uni-app(uniapp)入门基础与实战,其中还重点讲解了ES6、TypeScript这些基础知识,实战由两大价值5000元的真实企业级项目组成,分别是仿京东电商网站和仿美团微信点餐小程序,同时两大项目代码全部赠送,还赠送前后端架构模板,工作中直接使用。VUE和uni-app是目前热门的前端框架,本课程教你如何快速学会VUE和uni-app并应用到实战,教你如何解决内存泄漏,常用UI库的使用,自己封装组件和插件,正式上线白屏问题,性能优化、解决iphoneX“刘海”兼容性问题、微信支付、微信授权登录,获取位置在地图上显示,获取用户所在的城市和街道信息,微信小程序发布审核等。对正在工作当中或打算学习VUE和uni-app高薪就业的你来说,那么这门课程便是你手中的葵花宝典。学习技巧:学习当中不要只看,一定要多敲代码,如果碰到某一个知识点不是很明白,不要钻牛角尖,千万不要因为一个点,放弃整个森林,接着往下学,硬着头皮开发项目。只要能亲自开发一个完整的项目,你会发现不明白的地方自然而然就明白了,项目做出来就真正的学会了。此vue和uni-app课程以面试和实战为基础进行讲解,每个知识点都会让你知道在实际项目开发中如何使用,学习后,可以开发大型项目,增强逻辑思维,至少让你拥有3年以上开发经验的实力!代码和ppt均可下载!免费提供《企业级完整实战项目接口文档》,绝对可用
uniapp中,使用相机功能可能会遇到一些问题。引用中提到了一种解决方法,需要在app模块配置中勾选上相机选项。同时,在代码中也需要配置sourceType为相机和相册,以确保可以选择相机功能。此外,引用中还提到了在使用camera组件时可能会遇到空白或卡顿问题,可以尝试使用v-if来控制camera组件的显示与隐藏,以解决页面切换导致的问题。另外,为了确保相机权限的显示,可以在mounted中延迟一秒钟后再显示相机,同时通过loopGetCameraInfo方法查询相机状态并隐藏没有权限的情况。总的来说,以上的方法可以帮助解决uniapp打包app使用相机的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [uniapp打包app,调用相机功能时在真机调试可以,打包成app之后不行](https://blog.csdn.net/jieyucx/article/details/130319786)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [uniapp使用camera相关问题](https://blog.csdn.net/qq_40985294/article/details/128505300)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

碰磕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值