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
livePusher
to 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 usesetImage
, 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
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
ID camera
portrait camera
In this way, I successfully solved the flashback problem ~, if there is a problem, I will d in the comment area