基于JavaScript+HTML+cropper.js 摄像头拍照和拖动裁剪

1、基于Cropper.js v1.5.13版本实现摄像头拍照、推动和裁剪

页面引用 Cropper.js v1.5.13 和 cropper.css;

css

 .camera-crop {
        width: 500px;
        height:375px;
        float: left;
        border: 1px solid #f0f0f0;
        border-radius: 10px;
        margin: 5px;
        position: relative;
        overflow: hidden;
    }

    button{
        width: 100px;
        height: 49px;
        margin: 5px;
        padding: 10px;
        background-color: #0bb20c;
        border: 1px solid #0bb20c;
        border-radius: 10px;
        color: #fff;
        position: absolute;
        bottom: 0;
        z-index: 1;
    }
    .cropper-bg {
        background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMzTjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC");
    }
    .camera-crop-video{
        width: 500px;
        height:375px;
    }

    #video-container {
        width: 100%;
        height: 0;
        padding-bottom: 56.25%; /* 16:9 宽高比例,可以根据需要调整 */
        position: relative;
    }

    #video {
        width: 100%;
        height: 100%;
        position: relative;
        top: 0;
        left: 0;
    }

    .preview-container{
        background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMzTjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC");
        width: 500px;
        height:375px;
        position: relative;
        overflow: hidden;
        background-color: #fff;
        display: flex;
        justify-content: center;
        align-items: center;
    }

Js核心代码如下:

<script>
    // 获取视频流
    navigator.mediaDevices.getUserMedia({video: true})
        .then(function (stream) {
            var video = document.getElementById('video');
            video.srcObject = stream;
            video.play();
        })
        .catch(function (error) {
            console.log('访问摄像头失败:', error);
        });

    // 拍照
    var captureBtn = document.getElementById('capture-btn');
    captureBtn.addEventListener('click', function () {
        var video = document.getElementById('video');
        var cropperContainer = document.getElementById('cropper-container');
        var cropperImage = document.getElementById('cropper-image');

      

        // 将视频帧绘制到Canvas上
        var canvas = document.createElement('canvas');
        var context = canvas.getContext('2d');
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        context.drawImage(video, 0, 0, canvas.width, canvas.height);

        // 将Canvas内容转为图像数据URL
        var dataURL = canvas.toDataURL('image/png');

        // 创建新的裁剪图像元素
        var cropperImage = document.createElement('img');
        cropperImage.src = dataURL;
        cropperImage.alt = '裁剪图像';
        cropperContainer.innerText = '';
        cropperContainer.appendChild(cropperImage);

        // 显示裁剪图像
        //cropperImage.setAttribute('src', dataURL);

         // 初始化裁剪器
        const cropper = new Cropper(cropperImage, {
            dragMode: 'move',
            aspectRatio: 0.75, // 设置裁剪框的宽高比例
            viewMode: 1, // 设置裁剪框在容器中的显示模式
            autoCropArea: 0.8, // 设置裁剪框的初始大小
            cropmove:function (e) {
                // console.log(e);
                var croppedCanvas = cropper.getCroppedCanvas();
                var previewImage = document.getElementById('preview-image');
            	previewImage.src = croppedCanvas.toDataURL('image/png');
            }
        });


        // 保存裁剪图像
        var saveBtn = document.getElementById('save-btn');
        saveBtn.addEventListener('click', function () {
            // 获取裁剪后的图像数据
            var croppedCanvas = cropper.getCroppedCanvas();

            // 在裁剪后的Canvas上绘制文字描述
            var ctx = croppedCanvas.getContext('2d');
            ctx.font = '24px Arial';
            ctx.fillStyle = 'white';

            // 计算文字描述的位置
            var text = '2023年7月13日09:23:33';
            var textWidth = ctx.measureText(text).width;
            var x = (croppedCanvas.width - textWidth) / 2; // 水平居中
            var y = croppedCanvas.height - 20; // 距离底部 20px

            // 绘制文字描述
            ctx.fillText(text, x, y);

            // 将裁剪后的Canvas内容转为图像数据URL
            var croppedDataURL = croppedCanvas.toDataURL('image/png');

            var previewImage = document.getElementById('preview-image');
            previewImage.src = croppedCanvas.toDataURL('image/png');

            // 创建一个链接元素,用于下载图像
            var downloadLink = document.createElement('a');
            //downloadLink.href = croppedDataURL;
            //downloadLink.download = 'cropped_image.png';

            // 触发点击事件,开始下载图像
            //downloadLink.click();
        });
    });
</script>

navigator.mediaDevices.getUserMedia 是一个 Web API,用于在 Web 应用程序中访问用户的媒体设备,例如摄像头和麦克风,以捕获音频和视频流。它是 WebRTC(Web 实时通信)规范的一部分,允许开发者创建具有实时音视频功能的应用程序,如视频通话、视频录制或音频录制等。

navigator.mediaDevices.getUserMedia 方法用于请求用户授权访问其媒体设备。它接受一个 constraints(约束)参数,用于指定请求的媒体类型和其他选项。常见的约束属性包括:

  • audio:指定是否请求音频流,默认为 false
  • video:指定是否请求视频流,默认为 false
  • video 对象中的其他属性:用于指定视频的分辨率、帧率等参数。

当调用 navigator.mediaDevices.getUserMedia 方法时,浏览器会向用户显示一个权限请求对话框,询问用户是否允许访问他们的媒体设备。如果用户授权访问,该方法返回一个 Promise 对象,该对象在成功时解析为一个 MediaStream 对象,该对象代表用户的媒体流。开发者可以使用该流进行各种操作,如显示视频、录制音视频等。

以下是一个使用 navigator.mediaDevices.getUserMedia 方法的示例代码:

navigator.mediaDevices.getUserMedia({ video: true, audio: true })
  .then(function(stream) {
    // 获取到用户的媒体流后的处理逻辑
    // 可以将媒体流用于视频显示、音视频录制等操作
    var videoElement = document.getElementById('video');
    videoElement.srcObject = stream;
  })
  .catch(function(error) {
    // 处理访问媒体设备的错误
    console.log('访问媒体设备时出错:', error);
  });

在上面的示例中,我们使用 { video: true, audio: true } 的约束参数请求访问用户的摄像头和麦克风。getUserMedia 方法返回一个 Promise,成功时解析为一个 MediaStream 对象,代表用户的媒体流。我们可以将这个流分配给一个视频元素的 srcObject 属性,以显示视频。

需要注意的是,当执行此代码时,用户的浏览器会提示他们是否授权访问其媒体设备。此外,传递给 getUserMedia 的约束和选项可能因使用的浏览器和设备而有所不同。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

StephenYangKing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值