uniapp implements custom camera

origin

Recently, using uniapp to call the native camera is prone to flashback problems. I found a lot of tutorials on compressing pictures and optimizing codes. I said it didn’t help much!!

So started my solution

  • Use livePusherto achieve

Implement a custom camera

It is quite expandable, and can realize custom watermarks, ID card shooting, portrait shooting, etc.
Here I simply implement a camera function mainly to solve flashbacks

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

createcamera.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>

Some pictures are used here as icons to layout beautiful pictures, such as return icon, shooting icon

use

When you click to take a photo, camera页面you can jump to it
. Write the method in the page you need to use setImage, and you can get the temporary path of the returned picture,
and then upload it to the server through the upload picture api that comes with uniapp,
which avoids calling native camera

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

renderings

insert image description here

expand

What if you want to choose from the photo album and take pictures with your mobile phone? How to achieve it
Here, the photo album is selected to call the uniapp api, and
the mobile phone can jump to the custom camera page

Here you can write a pop-up window to let it choose, if you choose to choose a picture from the album then

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

If you use a camera to take pictures, follow the steps above

Implement multiple custom cameras

Here, I will paste the renderings, if necessary, get them in my blog resources

watermark camera

insert image description here

ID camera

insert image description here

portrait camera

insert image description here
In this way, I successfully solved the flashback problem ~, if there is a problem, I will d in the comment area

Guess you like

Origin blog.csdn.net/m_xiaozhilei/article/details/129406183