首页 > 其他分享 >IOS 和Android H5 打开摄像头拍照 使用navigator.MediaDevices.getUserMedia() 拍照

IOS 和Android H5 打开摄像头拍照 使用navigator.MediaDevices.getUserMedia() 拍照

时间:2022-08-29 16:01:10浏览次数:96  
标签: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/[email protected]/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
From: https://www.cnblogs.com/-youth/p/16636229.html

相关文章