手机浏览器实现拍照功能

1. 简单搭建结构和样式demo

<div>
     <video style="width: 100vw;height: 80vh;" id="preview" autoplay playsinline></video>
     <img id="img" width="100" src="" alt="">
     <canvas id="snapshot" style="display: none;"></canvas>
     <ul style="position: absolute;left: 0;top:0;display: flex;padding-left: 30px;">
            <li onClick="zoomFocus(0.5)" style="padding: 10px;background-color: #000;color:#fff;list-style: none;margin-right: 10px;">0.5</li>
            <li onClick="zoomFocus(1)" style="padding: 10px;background-color: #000;color:#fff;list-style: none;margin-right: 10px;">1</li>
            <li onClick="zoomFocus(2)" style="padding: 10px;background-color: #000;color:#fff;list-style: none;">2</li>
         </ul>
     <button onclick="takeSnapshot()">拍照</button>
</div>

2. 使用navigator.mediaDevices.getUserMedia api获取stream对象

 navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment" } })
            .then(function (stream) {
                document.getElementById('preview').srcObject = stream;
            }).catch(function (err) {
                console.log("无法获取媒体设备", err);
            });

3. 判断手机是否是竖直摆放还是横向摆放

  if ('orientation' in screen) {
                    // 监听屏幕方向变化事件
                    screen.orientation.addEventListener('change', () => {
                        console.log(`${screen.orientation.type === 'landscape-primary' ? '当前手机是横向摆放' : '当前手机是竖直摆放'}`);
                    });
                    // 获取当前屏幕方向
                    console.log(`${screen.orientation.type === 'landscape-primary' ? '当前手机是横向摆放' : '当前手机是竖直摆放'}`);
                } else {
                    console.log('浏览器不支持 Screen Orientation API');
                }

4. 判断手机屏幕和地方是否是水平还是垂直

                if (typeof DeviceOrientationEvent.requestPermission === 'function') {
                    //ios兼容
                    // 这个API存在,说明是iOS 13+,需要请求权限
                    DeviceOrientationEvent.requestPermission()
                        .then(permissionState => {
                            if (permissionState === 'granted') {
                                // 权限被授予,现在可以添加事件监听器了
                                window.addEventListener('deviceorientation', function (event) {
                                    const beta = event.beta;  // 前后倾斜角度 [-180,180]
                                    const gamma = event.gamma; // 左右倾斜角度 [-90,90]

                                    if (beta !== null && gamma !== null) {
                                        // 设备大致与地面平行
                                        if (Math.abs(beta) < 15 && Math.abs(gamma) < 15) {
                                            
                                            alert('设备与地面平行')
                                        }
                                        // 设备大致垂直于地面
                                        else if (Math.abs(beta) > 75 && Math.abs(gamma) < 15) {
                                         
                                            alert('设备垂直于地面')
                                        }
                                        else {
                                            
                                            alert('设备处于其他倾斜状态')
                                        }
                                    }
                                }, false);
                            } else {
                                console.log("设备方向访问权限未被授予");
                            }
                        })
                        .catch(console.error);
                } else if ('DeviceOrientationEvent' in window) {
                    //安卓兼容
                    window.addEventListener('deviceorientation', function (event) {
                        const beta = event.beta;  // 前后倾斜角度 [-180,180]
                        const gamma = event.gamma; // 左右倾斜角度 [-90,90]

                        if (beta !== null && gamma !== null) {

                            if (Math.abs(beta) < 15 && Math.abs(gamma) < 15) {
                                // 设备大致与地面平行
                                console.log('设备与地面平行')
                            } else if (Math.abs(beta) > 75 && Math.abs(gamma) < 15) {
                                // 设备大致垂直于地面
                                console.log('设备垂直于地面')
                            }
                            else {
                                console.log('设备处于其他倾斜状态')
                            }
                        }
                    }, false);
                }

5. 调整手机摄像头变焦倍数

async function zoomFocus(zoom) {
            try {
                this.stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment" } });
                document.getElementById('preview').srcObject = this.stream;
                if (!this.stream) return;
                const track = this.stream.getVideoTracks()[0];
                const capabilities = track.getCapabilities();
                // 检查是否支持焦距调整
                if (!capabilities.zoom) return;
                track.applyConstraints({
                    advanced: [{ zoom: zoom }]
                }).catch(e => console.error(e));
                
            } catch (error) {
                console.error('启动摄像头失败:', error);
            }
        }

以下为完整代码

<!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>
</head>

<body>
    <div>
        <video style="width: 100vw;height: 80vh;" id="preview" autoplay playsinline></video>
        <img id="img" width="100" src="" alt="">
        <canvas id="snapshot" style="display: none;"></canvas>
        <ul>
           <li onClick="zoomFocus(0.5)">0.5</li>
           <li onClick="zoomFocus(1)">1</li>
           <li onClick="zoomFocus(2)">2</li>
        </ul>
        <button onclick="start()">拍照</button>

    </div>

    <script>
        navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment" } })
            .then(function (stream) {
                document.getElementById('preview').srcObject = stream;
                //判断手机是否是竖直摆放还是横向摆放
                if ('orientation' in screen) {
                    // 监听屏幕方向变化事件
                    screen.orientation.addEventListener('change', () => {
                        console.log(`${screen.orientation.type === 'landscape-primary' ? '当前手机是横向摆放' : '当前手机是竖直摆放'}`);
                    });
                    // 获取当前屏幕方向
                    console.log(`${screen.orientation.type === 'landscape-primary' ? '当前手机是横向摆放' : '当前手机是竖直摆放'}`);
                } else {
                    console.log('浏览器不支持 Screen Orientation API');
                }
                //判断手机屏幕和地方是否是水平还是垂直
                if (typeof DeviceOrientationEvent.requestPermission === 'function') {
                    //ios兼容
                    // 这个API存在,说明是iOS 13+,需要请求权限
                    DeviceOrientationEvent.requestPermission()
                        .then(permissionState => {
                            if (permissionState === 'granted') {
                                // 权限被授予,现在可以添加事件监听器了
                                window.addEventListener('deviceorientation', function (event) {
                                    const beta = event.beta;  // 前后倾斜角度 [-180,180]
                                    const gamma = event.gamma; // 左右倾斜角度 [-90,90]

                                    if (beta !== null && gamma !== null) {
                                        // 设备大致与地面平行
                                        if (Math.abs(beta) < 15 && Math.abs(gamma) < 15) {
                                            console.log("设备与地面平行");
                                        }
                                        // 设备大致垂直于地面
                                        else if (Math.abs(beta) > 75 && Math.abs(gamma) < 15) {
                                            console.log("设备垂直于地面");
                                        }
                                        else {
                                            console.log("设备处于其他倾斜状态");
                                        }
                                    }
                                }, false);
                            } else {
                                console.log("设备方向访问权限未被授予");
                            }
                        })
                        .catch(console.error);
                } else if ('DeviceOrientationEvent' in window) {
                    //安卓兼容
                    window.addEventListener('deviceorientation', function (event) {
                        const beta = event.beta;  // 前后倾斜角度 [-180,180]
                        const gamma = event.gamma; // 左右倾斜角度 [-90,90]

                        if (beta !== null && gamma !== null) {

                            if (Math.abs(beta) < 15 && Math.abs(gamma) < 15) {
                                // 设备大致与地面平行
                                alert('设备与地面平行')
                            } else if (Math.abs(beta) > 75 && Math.abs(gamma) < 15) {
                                // 设备大致垂直于地面
                                alert('设备垂直于地面')
                            }
                            else {
                                alert('设备处于其他倾斜状态')
                            }
                        }
                    }, false);
                }
            })
            .catch(function (err) {
                console.log("无法获取媒体设备", err);
            });

        function start() {
            let video = document.getElementById('preview');
            let canvas = document.getElementById('snapshot');
            let img = document.getElementById('img');
            let context = canvas.getContext('2d');

            canvas.width = video.videoWidth;
            canvas.height = video.videoHeight;
            context.drawImage(video, 0, 0, canvas.width, canvas.height);

            // 导出图片
            let imageUrl = canvas.toDataURL('image/png');
            // 可以将 imageUrl 用于显示或保存操作
            console.log(imageUrl)
            img.src = imageUrl
        }
         async function zoomFocus(zoom) {
            try {
                this.stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment" } });
                document.getElementById('preview').srcObject = this.stream;
                if (!this.stream) return;
                const track = this.stream.getVideoTracks()[0];
                const capabilities = track.getCapabilities();
                // 检查是否支持焦距调整
                if (!capabilities.zoom) return;
                track.applyConstraints({
                    advanced: [{ zoom: zoom }]
                }).catch(e => console.error(e));
                
            } catch (error) {
                console.error('启动摄像头失败:', error);
            }
        }
    </script>
</body>

</html>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值