- 原生微信小程序的拍照 截取
- 小程序的摄像(30S)
- 照片的截取
- 照片,视频的上传
.wxml
<view class="cameraParent" wx:if="{{picture}}">
<view class="cameraTop">
<p wx:if="{{dataNum == '4'}}">00:00:{{videoTimeText}}</p>
</view>
<canvas id="myCanvas" canvas-id="myCanvas" />
<camera class="camera" device-position="{{devicePosition}}" binderror="error">
<cover-view class="id_m">
<cover-view class="texttop">
<cover-image wx:if="{{dataNum == '1'}}" class="img" id="cover_image" src="/assets/img/idCardFront.png"></cover-image>
<cover-image wx:elif="{{dataNum == '2'}}" class="img" id="cover_image" src="/assets/img/idCardBack.png"></cover-image>
<cover-view wx:else class="img"></cover-view>
</cover-view>
<cover-view class="textcenter">
<cover-view class="viewText" wx:if="{{dataNum == '1'}}">请将身份证头像徽面放在框内</cover-view>
<cover-view class="viewText" wx:elif="{{dataNum == '2'}}">请将身份证国徽面放在框内</cover-view>
<cover-view class="viewText" wx:elif="{{dataNum == '3'}}">请手持证件进行拍照</cover-view>
<cover-view class="viewText viewText1" wx:elif="{{dataNum == '4'}}">
<cover-view class="_text1">请在拍摄时朗读如下话术:</cover-view>
<cover-view class="_text1">我是XX(姓名),</cover-view>
<cover-view class="_text1">身份证身份证号是XXXXXX</cover-view>
</cover-view>
</cover-view>
</cover-view>
</camera>
<view class="bodyRelease">
<view class="_title" wx:if="{{dataNum == '1'|| dataNum == '2'||dataNum == '3'}}">照片</view>
<view class="_title" wx:elif="{{dataNum == '4'&& !shoot }}">摄像</view>
<view class="_title" wx:else>视频</view>
<view class="butIncident">
<view bindtap="backCamera" class="cancel">取消</view>
<cview class="btnEvent">
<image bindtap="shutter" class="{{down?'img2':''}} img1" src="/assets/img/one.png" mode="widthFix" lazy-load="false" wx:if="{{dataNum == '1'|| dataNum == '2'||dataNum == '3'}}"></image>
<image bindtap="shutterstart" class="img1" src="/assets/img/two.png" mode="widthFix" lazy-load="false" wx:elif="{{dataNum == '4'&& !shoot }}"></image>
<image bindtap="shutterend" class="img1" src="/assets/img/three.png" mode="widthFix" lazy-load="false" wx:else></image>
</cview>
<view bindtap="switch" class="_shift">
<image class="img2" src="/assets/img/shift.png" lazy-load="false"></image>
</view>
</view>
</view>
</view>
<view class="artificialCertification" wx:else>
<view class="pic">
<view class="exhibition">
<image src="{{pic1}}" mode="widthFix" lazy-load="false" bindtap="chooseType" data-num='1' bindlongpress="handleLongPress"></image>
<p>点击上传身份证人像面</p>
</view>
<view class="exhibition">
<image src="{{pic2}}" mode="widthFix" lazy-load="false" bindtap="chooseType" data-num='2' bindlongpress="handleLongPress"></image>
<p>点击上传身份证国徽面</p>
</view>
<view class="exhibition">
<image src="{{pic3}}" mode="widthFix" lazy-load="false" bindtap="chooseType" data-num='3' bindlongpress="handleLongPress"></image>
<p>点击上传手持身份证照片</p>
<view class="_text">拍摄时,手持本人身份证,脸部清晰且不能被遮挡;确保身份证上的所有信息清晰可见、完整(没有被遮挡或者被手指捏住)</view>
</view>
<view class="exhibition" bindtap="chooseType" data-num='4' bindlongpress="handleLongPress">
<image src="{{pic4}}" mode="widthFix" lazy-load="false" wx:if="{{!isIfVideo}}"></image>
<video id="video" src="{{pic4}}" wx:else controls="{{true}}" show-center-play-btn='{{false}}' show-play-btn="{{false}}"></video>
<p>点击上传手持身份证视频</p>
<view class="_text">手持身份证拍摄视频,视频话术为:“我是XX(姓名),身份证身份证号是XXXXXX”</view>
</view>
</view>
<view class="btn">
<button bindtap="submit" disabled="{{disabledBut}}">提交</button>
<button bindtap="backNext" class="back">返回</button>
</view>
</view>
.scss
page {
width: 100%;
height: 100%;
}
.cameraParent {
height: 100vh;
width: 100vw;
overflow: hidden;
position: relative;
.cameraTop {
background: #000000;
height: 6.6vh;
width: 100vw;
text-align: center;
line-height: 6.6vh;
font-family: PingFangSC-Regular;
font-size: 40rpx;
color: #ffffff;
}
#myCanvas {
width: 100vw;
height: 75vh;
position: absolute;
z-index: -999;
opacity: 0;
}
.camera {
height: 75vh;
width: 100vw;
z-index: 1;
position: relative;
.id_m {
width: 100vw;
height: 75vh;
position: relative;
.texttop {
width: 100vw;
.img {
display: block;
background-color: rgba(0, 0, 0, 0);
width: 92.3vw;
min-height: 58.42vw;
height: auto;
margin: 22% auto 0;
border-radius: 5%;
}
}
.textcenter {
position: absolute;
bottom: 6.3vh;
width: 100vw;
display: flex;
justify-content: center;
.viewText {
height: auto;
display: inline-block;
font-family: PingFangTC-Regular;
font-size: 28rpx;
color: #ffffff;
background: rgba(0, 0, 0, 0.4);
border-radius: 16rpx;
padding: 20rpx 30rpx;
._text1 {
line-height: 32rpx;
}
}
}
}
}
.bodyRelease {
background: #000000;
height: 18.4vh;
widows: 100vw;
._title {
width: 100vw;
font-family: PingFangTC-Regular;
font-size: 28rpx;
height: 6.3vh;
line-height: 6.3vh;
color: #29d1ff;
text-align: center;
}
.butIncident {
margin: 0 4vw;
height: 10vh;
display: flex;
justify-content: space-between;
.cancel {
padding-left: 1vh;
height: 10vh;
width: 9vh;
line-height: 10vh;
font-family: PingFangTC-Regular;
font-size: 30rpx;
color: #ffffff;
}
.btnEvent {
height: 10vh;
width: 10vh;
.img1 {
height: 10vh;
width: 10vh;
transform: scale(1);
}
.img2 {
transform: scale(0.85);
}
}
._shift {
height: 10vh;
width: 10vh;
display: flex;
.img2 {
margin: auto;
width: 80%;
height: 80%;
}
}
}
}
.aa {
height: 50vh !important;
width: 100vw;
}
}
.artificialCertification {
width: 100%;
min-height: 100%;
padding: 28rpx 40rpx 96rpx 40rpx;
box-sizing: border-box;
.pic {
width: 100%;
.exhibition {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 96rpx;
image {
width: 44vw;
height: 27.85vw;
display: block;
}
#video {
width: 88vw;
height: 44vw;
}
p {
opacity: 0.6;
font-family: PingFangSC-Regular;
font-size: 26rpx;
color: #233347;
letter-spacing: 0.26rpx;
text-align: justify;
margin-top: 16rpx;
}
._text {
opacity: 0.8;
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #233347;
letter-spacing: 0.28rpx;
text-align: justify;
margin-top: 50rpx;
}
}
}
.btn {
width: 100%;
padding: 0 80rpx;
box-sizing: border-box;
margin-top: 96rpx;
button {
width: 100%;
height: 90rpx;
background: #3874f6;
box-shadow: 0 4rpx 8rpx 0 rgba(56, 116, 246, 0.1);
border-radius: 16rpx;
font-family: PingFangSC-Regular;
font-size: 28rpx;
color: #ffffff;
letter-spacing: 0.38rpx;
line-height: 90rpx;
padding: 0;
margin-top: 64rpx;
font-weight: 200;
}
.back {
background: #f2f2f2;
margin-top: 24rpx;
color: #3874f6;
}
}
}
.js
Page({
/**
* 页面的初始数据
*/
data: {
pic1: "../../assets/img/pic1.png",//为拍照时展示的图片
pic2: "../../assets/img/pic2.png",//为拍照时展示的图片
pic3: "../../assets/img/pic3.png",//为拍照时展示的图片
pic4: "../../assets/img/pic4.png",//为录像时展示的图片
isIfVideo: false, //控制视频是否上传
arr: [undefined, undefined, undefined, undefined], //提交数据连接
disabledBut: true, //是否提交数据
picture: false, //是否启用相机
devicePosition: "back", //摄像头的位置 front back
shoot: false, //是否开始拍摄
videoTime: 30, //拍摄定时
videoTimeText: 30, //时间同步器
timeSetData: "", //定时器
down: false, //是否点击拍照按钮
},
/***
* 提交接口
*/
submit() {
/***
*确定相关照片都已经上传
*上传成功后会生产对应的文件路径
*/
if (!this.data.arr.includes(undefined)) {
this.setData({
disabledBut: true,//启动确定按钮禁用 防止多次点击
});
wx.showLoading({
title: "提交中",
});
let params = {
idCardFrontside: this.data.arr[0],
idCardBackside: this.data.arr[1],
lifePortrait: this.data.arr[2],
authenticationVideo: this.data.arr[3],
};
//自己分装的ajax请求
api.connect("/personalUserService/personalUsers/uploadAuthenticationInformatio",
{
data: params,
method: "POST",
}
)//对应自己的接口对接
.then((res) => {
//接口成功的操作
})
.catch(() => {
//接口错误的操作
});
} else {
let text = "上传图片或视频不能为空";
switch (this.data.arr.indexOf(undefined)) {
case 0:
text = "身份证人像面不能为空";
break;
case 1:
text = "身份证国徽面不能为空";
break;
case 2:
text = "手持身份证照片不能为空";
break;
case 3:
text = "手持身份证视频不能为空";
break;
default:
text = "上传图片或视频不能为空";
break;
}
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function () {
this.ctx = wx.createCameraContext();//初始化 创建 camera 上下文 CameraContext 对象。
this.ctx_A = wx.createCanvasContext("myCanvas"); //画布
},
/**
* pic图片,视频上传还是预览
*/
chooseType(e) {
let num = e.currentTarget.dataset.num;
if (this.data.arr[num - 1]) {
if (num < 4) {
wx.previewImage({
current: this.data["pic" + num], // 当前显示图片的http链接
urls: [this.data["pic" + num]], // 需要预览的图片http链接列表
});
} else {
//如果是视屏则调去video播放
let vid = wx.createVideoContext("video");
vid.play();
}
} else {
this.sourceSelection(num);
}
},
/**
* 长按事件
* 重新上传
*/
handleLongPress(e) {
this.sourceSelection(e.currentTarget.dataset.num);
},
/**
* 相机页面返回
*/
backCamera() {
this.setData({
picture: false,
});
wx.hideLoading();
clearTimeout(this.data.timeSetData);
},
/**
* 点击自定义拍照按钮
*/
shutter() {
this.setData({
down: true,
});
wx.showLoading({
title: "上传压缩中...",
mask: true,
});
this.ctx.takePhoto({
quality: "high",
success: (res) => {
switch (this.data.dataNum) {
case "1":
this.generate(res.tempImagePath);
break;
case "2":
this.generate(res.tempImagePath);
break;
case "3":
wx.compressImage({
src: res.tempImagePath, // 图片路径
success: (item) => {
this.getUrl(item.tempFilePath, 5);
},
});
break;
default:
break;
}
},
});
},
/**
* 图片截取
* 自定义计算位置 截取自己需要的那一部分图片
*/
generate(imgSrc) {
wx.createSelectorQuery()
.select("#cover_image")
.boundingClientRect((rect) => {
this.ctx_A.drawImage(
imgSrc,
0,
0,
wx.getSystemInfoSync().windowWidth,
wx.getSystemInfoSync().windowHeight * 0.75
);
this.ctx_A.draw(true, () => {
wx.canvasToTempFilePath({
//调用方法,开始截取
x: rect.left,
y: rect.top - wx.getSystemInfoSync().windowHeight * 0.066,
width: rect.width,
height: rect.height,
destWidth: rect.width,
destHeight: rect.height,
canvasId: "myCanvas",
quality: 1,
success: (res) => {
this.getUrl(res.tempFilePath, 5);
},
});
});
})
.exec();
},
/**
* 点击自定义摄像开始按钮
*/
shutterstart() {
wx.showLoading({
title: "Loading...",
mask: true,
});
this.ctx.startRecord({
success: () => {
this.setDataTime();
},
});
},
/**
* 定时器
* 防止视屏录制时间过长限制
* 原生限制30S
*/
setDataTime() {
this.data.timeSetData = setInterval(() => {
if (this.data.videoTime < 0) {
wx.showToast({
title: "录制视频应小于30s",
icon: "none",
duration: 2000,
});
this.setData({
shoot: false,
videoTime: 30,
videoTimeText: 30,
});
clearTimeout(this.data.timeSetData);
} else {
wx.hideLoading();
this.setData({
shoot: true,
videoTimeText:
this.data.videoTime.toString().length == 1
? `0${this.data.videoTime}`
: this.data.videoTime,
videoTime: --this.data.videoTime,
});
}
}, 1000);
},
/**
* 点击自定义摄像结束按钮
*/
shutterend() {
clearTimeout(this.data.timeSetData);
wx.showLoading({
title: "上传压缩中...",
mask: true,
});
this.ctx.stopRecord({
compressed: true,
success: (res) => {
this.setData({
shoot: false,
});
this.getUrl(res.tempVideoPath, 4);
},
});
},
/**
* 相机摄像头方向转换
*/
switch() {
this.setData({
devicePosition: this.data.devicePosition == "back" ? "front" : "back",
});
},
/**
* 调取获取方式
*/
sourceSelection(num = 1) {
this.setData({
picture: true,
dataNum: num,
devicePosition: "back",
shoot: false,
videoTimeText: 30,
videoTime: 30,
down: false,
});
},
/**
* 根据本地地址返回url
*/
getUrl(file, fileType) {
wx.getFileInfo({
filePath: file,
success(res) {
console.log(res.size / 1024);
},
});
wx.uploadFile({
url: //自己的上传接口,
header: {
"Content-Type": "multipart/form-data",
token: //,
},
filePath: file,
name: "file",
formData: {
fileType: fileType,
},
success: (res) => {
try {
let data = JSON.parse(res.data);
if (data.code == "2000") {
switch (this.data.dataNum) {
case "1":
this.setData({
picture: false,
pic1: file,
["arr[0]"]: data.data,
});
break;
case "2":
this.setData({
picture: false,
pic2: file,
["arr[1]"]: data.data,
});
break;
case "3":
this.setData({
picture: false,
pic3: file,
["arr[2]"]: data.data,
});
break;
case "4":
this.setData({
picture: false,
pic4: file,
isIfVideo: true,
["arr[3]"]: data.data,
});
break;
default:
break;
}
this.getUrlOVer();
}
} catch (error) {
wx.showToast({
title: "提交失败",
icon: "none",
duration: 2000,
});
this.backCamera();
}
},
});
},
/**
* 返回url调取函数
*/
getUrlOVer() {
setTimeout(() => {
this.backCamera();
wx.showToast({
title: `上传成功`,
icon: "none",
duration: 2000,
});
if (!this.data.arr.includes(undefined))
this.setData({
disabledBut: false,
});
}, 0);
},
});
😋😋