react脚手架下pc端拍照功能
import React, { Component } from 'react';
import "./index.less";
var mediaStreamTrack; //拍照
class Audio extends Component {
constructor(props) {
super(props);
this.state = {
isShot: false,//是否点击弹框拍摄按钮
showMod: false,
img:'', //拍摄的照片
}
}
componentDidMount() {
}
//点击页面拍照按钮
readyVideo = (e) => {
var that = this;
that.setState({
showMod: true,
isShot: false,
}, () => {
var myVideo = document.getElementById('myVideo');
var myCanvas = document.getElementById('myCanvas');
let videoObj = {
'audio': false,
'video': true,
video: {
// width: { min: 1024, ideal: 4000, max: 2048 },
// height: { min: 768, ideal: 1200, max: 1536 }
}
}
navigator.getMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMeddia || navigator.msGetUserMedia;
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia(videoObj).then(function (stream) {
mediaStreamTrack = typeof stream.stop === 'function' ? stream : stream.getTracks()[0];
myVideo.srcObject = stream;
myVideo.play();
}).catch(function (err) {
console.log(err);
})
}
// 使用旧方法打开摄像头
else if (navigator.getMedia) {
navigator.getMedia(videoObj, function (stream) {
mediaStreamTrack = stream.getTracks()[0];
myVideo.srcObject = stream;
myVideo.play();
}, function (err) {
console.log(err);
});
}
})
}
//弹框拍摄
shot = () => {
var myVideo = document.getElementById('myVideo');
var myCanvas = document.getElementById('myCanvas').getContext('2d');
myCanvas.drawImage(myVideo, 0, 0, 600, 600);
this.setState({
isShot: true,
})
}
// 确认此次拍摄照片
sureShot = () => {
let that=this;
var myCanvas = document.getElementById('myCanvas');
var img = myCanvas.toDataURL("image/png");
that.setState({
img
});
that.cancel();
}
//取消
cancel = () => {
//关闭摄像头
var myVideo = document.getElementById('myVideo');
if (myVideo) { mediaStreamTrack && mediaStreamTrack.stop(); }
this.setState({
isShot: false,
showMod: false,
})
}
render() {
let { isShot, showMod ,img} = this.state;
return (
<div className='video_page'>
<button onClick={this.readyVideo}>拍照</button>
{showMod
?(<div className='video_model'>
<div className='video_box'>
<video id='myVideo' width='300' height='300'></video>
<canvas id='myCanvas' width='600' height="600"
style={{width:'300px',height:'300px'}}
></canvas>
</div>
<button onClick={this.shot}>{isShot?'重拍':'拍照'}</button>
{isShot?(<button onClick={this.sureShot}>确认</button>):null}
<button onClick={this.cancel}>取消</button>
</div>)
: null}
{img ? <img src={img} />: null}
</div>
)
}
}
export default Audio;
下面是less文件
.video_page {
position: relative;
width: 100%;
padding: 15px 2%;
box-sizing: border-box;
>img{
display: block;
width: 300px;
height: 300px;
}
.video_model{
position: absolute;
z-index: 2;
// top: 20%;
// left: 20%;
box-shadow: 0 0 5px @color_cropper_box;
.video_box{
display: flex;
margin-top: 10px;
margin-bottom: 10px;
>video{
border: 1px solid #ccc;
object-fit:fill;
margin-right: 10px;
}
>canvas{
border: 1px solid #ccc;
}
}
>button {
height: 30px;
line-height: 28px;
padding: 0 20px;
letter-spacing: 2px;
color: #333;
border: 1px solid #333;
border-radius: 5px;
margin-right: 14px;
font-size: 12px;
margin-bottom: 10px;
background-color: #fff;
}
}
}
调用摄像头时,如果对摄像头没有要求就直接在readyVideo()方法中设置videoObj为
let videoObj = {
'audio': false,
'video': true,
}
如果使用了高拍仪等外接摄像头,不想用浏览器的选择摄像头进行选择,想在打开摄像头的时候就优先使用高拍仪
就需要在videoObj中设置video的质量,直接设置成高像素,
缺点就是 如果设置了高像素而设备不能满足这个像素,就会造成获取摄像头为空白
let videoObj = {
'audio': false,
'video': true,
video: {
width: { min: 1024, ideal: 4000, max: 2048 },
height: { min: 768, ideal: 1200, max: 1536 }
}
}
拍摄完成后,将video转化为canvas,像素是有些模糊的
如果对图片质量有要求的话,可以将canvas的宽和高都扩大两倍,但是在style中将canvas的宽高设置为和原来一致,
<video id='myVideo' width='300' height='300'></video>
<canvas id='myCanvas' width='600' height="600"
style={{width:'300px',height:'300px'}}
></canvas>
确认图片的方法中也是设置为600*600
//弹框拍摄
shot = () => {
var myVideo = document.getElementById('myVideo');
var myCanvas = document.getElementById('myCanvas').getContext('2d');
myCanvas.drawImage(myVideo, 0, 0, 600, 600);
this.setState({
isShot: true,
})
}
实际上是你生成的图片,你的canvas是600*600的,只是在显示上是300*300的