标签:MediaDevices 拍照 ctx canvas height width video getUserMedia navigator
<!DOCTYPE html> <html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.7.10/dist/vue.js"></script> <style> *{ margin:0;padding: 0; } .video-wrap { overflow: hidden; width: 30vw; height: 45vw; border-radius: 100%; display: flex; justify-content: center; align-items: center; position: relative; z-index: 3; background-color: #ccc; }
.pic_video { width: 60vw; height: 60vw; transform: rotateY(180deg); z-index: 6; position: relative; }
.buddon { display: flex;
}
.warm_title2 { background-color: rgb(150, 150, 231); color: #fff; width: 100px; height: 40px; line-height: 40px; text-align: center; margin-right: 10px; }
#canvas { height: 40vw; transform: rotateY(180deg); display: none; }
img { transform: rotateY(180deg); } .flex{ display: flex; justify-content: center; margin-top:20px
} .center{ margin:0 auto; } #video{ mix-blend-mode: normal; outline: -webkit-focus-ring-color auto 0px; } </style> </head>
<body> <div id="app"> <div class="buddon flex" v-if="imginfo ==''"> <div class="warm_title2" @click='moveToCameraAVG()'>打开摄像头</div> <div @click='captureAvg' class="warm_title2">拍照</div> </div> <div class="buddon flex" v-else> <div @click='reloadPage' class="warm_title2">重新拍照</div> </div> <div v-if="imginfo!==''" class="flex"> <img :src="imginfo" /> </div> <div class="flex" v-else> <div class="video-wrap" > <video id="video" class="pic_video" playsinline autoplay x5-video-player-type="h5"></video> </div> </div> <canvas id="canvas" class="canvas_pic" style='margin: 0;padding: 0;'></canvas> <!-- <div> img绘制: <img v-if="imginfo!==''" :src="imginfo" /> </div> <div> canvas绘制 : <canvas id="canvas" class="canvas_pic" style='margin: 0;padding: 0;'></canvas> </div> -->
</div> </body> <script src="./jquery.js"></script> <script> new Vue({ el: '#app', data() { return { imginfo: '' } }, methods: {
// 头像相机
moveToCameraAVG() {
var self = this;
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {};
}
if (navigator.mediaDevices.getUserMedia === undefined) {
navigator.mediaDevices.getUserMedia = function (constraints) {
var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia;
if (!getUserMedia) {
return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
}
return new Promise(function (resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject);
});
}
}
if (window.stream) {
window.stream.getTracks().forEach(track => {
track.stop();
});
}
var constraints = window.constraints = {
audio: false,
video: {
sourceId: 'default',
facingMode: { exact: "user" }
}
};
navigator.mediaDevices.getUserMedia(constraints)
.then(function (stream) {
var video = document.getElementById('video');
try {
window.stream = stream;
video.srcObject = stream;
} catch (error) {
video.src = window.URL.createObjectURL(stream);
}
self.localMediaStream = stream;
video.play();
})
.catch(function (err) {
alert(err.name + ": " + err.message);
});
}, imageToCircle(picUrl) { let radius, diameter, canvas, ctx; let img = new Image() img.setAttribute('crossOrigin', 'anonymous'); // 解决图片跨域访问失败 img.src = picUrl var video = document.getElementById('video'); return new Promise((reslove) => { img.addEventListener("load", () => { let height = $('.video-wrap').height() let width = $('.video-wrap').width() radius = width / 2; let canvas = document.createElement('canvas'); if (!canvas.getContext) { // 判断浏览器是否支持canvas,如果不支持在此处做相应的提示 console.log('您的浏览器版本过低,暂不支持。'); return false; } canvas.width = width; canvas.height = height;
ctx = canvas.getContext("2d"); ctx.clearRect(0, 0, width, height);
// 描边 ctx.save(); //save和restore可以保证样式属性只运用于该段canvas元素 ctx.strokeStyle = '#ffffff'; //设置边线的颜色 ctx.lineWidth = 0; ctx.beginPath(); //开始路径 //ctx.ellipse(radius, radius, radius - 5, 0, Math.PI * 2); //画一个整圆. const radiusX = width / 2 const radiusY = height / 2 ctx.ellipse(radiusX, radiusY, radiusX, radiusY, 0, 0, Math.PI * 2, true)
// 参数(从左到右): // (起点x,起点y,半径x,半径y,旋转的角度,起始角,结果角,顺时针还是逆时针) ctx.stroke(); //绘制边线
// 截圆形图 ctx.save(); ctx.beginPath(); ctx.ellipse(radiusX, radiusY, radiusX, radiusY, 0, 0, Math.PI * 2, true) ctx.clip();
const videoRatio = video.videoHeight / video.videoWidth // 原视频比例 const domHeight = video.offsetHeight // 元素宽高 const domWidth = video.offsetWidth let realW = 0, realH = 0; if (domHeight / domWidth >= videoRatio) { // 宽度占满,计算高度 realW = domWidth realH = domWidth * videoRatio } else { // 高度占满,计算宽度 realH = domHeight realW = domHeight / videoRatio }
let x = realW - width, y = realH - height, swidth = width, sheight = height
ctx.drawImage(img, x / 2, y / 2, swidth, sheight, 0, 0, swidth, height); ctx.restore(); // toDataURL()是canvas对象的一种方法,用于将canvas对象转换为base64位编码 let dataURL = canvas.toDataURL('image/png'); reslove(dataURL)
}, false)
}) },
//停止摄像机
stopCapture: function () {
var video = document.getElementById('video');
if (!video.srcObject) return
let stream = video.srcObject
let tracks = stream.getTracks();
tracks.forEach(track => {
track.stop()
})
},
// 头像照片
async captureAvg() {
var vm = this;
var video = document.getElementById('video');
var canvas = document.getElementById('canvas'), ctx = canvas.getContext('2d') const videoRatio = video.videoHeight / video.videoWidth // 原视频比例 const domHeight = video.offsetHeight // 元素宽高 const domWidth = video.offsetWidth let realW = 0, realH = 0; if (domHeight / domWidth >= videoRatio) { // 宽度占满,计算高度 realW = domWidth realH = domWidth * videoRatio } else { // 高度占满,计算宽度 realH = domHeight realW = domHeight / videoRatio }
CWidth = realW, CHeight = realH;//获取屏幕大小让canvas自适应 canvas.width = CWidth; canvas.height = realH;
if (vm.localMediaStream) {
ctx.drawImage(video, 0, 0, CWidth, CHeight);
var dataURL = canvas.toDataURL('image/jpeg'); //dataURL = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA' const roundUrl = await this.imageToCircle(canvas.toDataURL('image/png')); vm.imginfo = roundUrl;
// 停止摄像机
video.pause();
this.stopCapture();
}
}, reloadPage(){ location.reload() } } }) </script>
</html>
标签:MediaDevices,拍照,ctx,canvas,height,width,video,getUserMedia,navigator 来源: https://www.cnblogs.com/-youth/p/16636229.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。