JS打开摄像头并截图上传

直入正题,JS打开摄像头并截图上传至后端的一个完整步骤

1. 打开摄像头主要用到getUserMedia方法,然后将获取到的媒体流置入video标签

2. 截取图片主要用到canvas绘图,使用drawImage方法将video的内容绘至canvas中

3. 将截取的内容上传至服务器,将canvas中的内容转为base64格式上传,后端(PHP)通过file_put_contents将其转为图片

要注意的是,在chrome以外的浏览器中,使用摄像头或多或少会出现一些问题,可能也是老问题了,所以以下代码主要基于chrome使用

比如在最新版FireFox中的报错,不知为啥

1. 打开摄像头

getUserMedia 有新版本和旧版本两种,建议使用新版本

旧版本位于navigator 对象下,根据浏览器不同有所不同

// 获取媒体方法(旧方法)
    navigator.getMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMeddia || navigator.msGetUserMedia;
if (navigator.getMedia) {
        navigator.getMedia({
            video: true
        }, function(stream) {
            mediaStreamTrack = stream.getTracks()[0];

            video.src = (window.URL || window.webkitURL).createObjectURL(stream);
            video.play();
        }, function(err) {
            console.log(err);
        });
    }

第一个参数中指示需要使用视频(video)或音频(audio),更多参见文档

第二个参数中指示调用成功后的回调,其中带一个参数(MediaStream),在旧版本中可以直接通过调用MediaStream.stop() 来关闭摄像头,不过在新版之中已废弃。需要使用MediaStream.getTracks()[index].stop() 来关闭相应的Track

第三个参数指示调用失败后的回调

新版本位于navigator.mediaDevices 对象下

if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia({
            video: true,
            audio: true
        }).then(function(stream) {
            console.log(stream);

            mediaStreamTrack = typeof stream.stop === ‘function‘ ? stream : stream.getTracks()[1];

            video.src = (window.URL || window.webkitURL).createObjectURL(stream);
            video.play();
        }).catch(function(err) {
            console.log(err);
        })
    }

与旧版类似,不过该方法返回了一个Promise对象,可以使用then和catch表示成功与失败的回调

更多参见文档

需要注意的是,MediaStream.getTracks() 返回的Tracks数组是按第一个参数倒序排列的

比如现在定义了

{
    video: true,
    audio: true
}

想关闭摄像头,就需要调用MediaStream.getTracks()[1].stop();

同理,0对应于audio的track

使用createObjectURL 将MediaStream写入video标签,就能够存储实时的媒体流数据(也可以方便的实时查看画面)

旧版本中webkitURL 对象以不被支持,需要使用URL对象

  <video width="200" height="150"></video>
    <canvas width="200" height="150"></canvas>

    <p>
        <button id="snap">截取图像</button>
        <button id="close">关闭摄像头</button>
        <button id="upload">上传图像</button>
    </p>

    <img id="uploaded" width="200" height="150" />

2. 截取图像

将内容写入即可

// 截取图像
    snap.addEventListener(‘click‘, function() {
        context.drawImage(video, 0, 0, 200, 150);
    }, false);

3. 关闭摄像头

// 关闭摄像头
    close.addEventListener(‘click‘, function() {
        mediaStreamTrack && mediaStreamTrack.stop();
    }, false);

4. 上传截取的图像

canvas.toDataURL(‘image/png‘)

// 上传截取的图像
    upload.addEventListener(‘click‘, function() {
        jQuery.post(‘/uploadSnap.php‘, {
            snapData: canvas.toDataURL(‘image/png‘)
        }).done(function(rs) {
            rs = JSON.parse(rs);

            console.log(rs);

            uploaded.src = rs.path;
        }).fail(function(err) {
            console.log(err);
        });
    }, false);

而这里的后端(PHP)则将获取的内容转换成图像文件保存

需要注意的是,要将base64的头部信息字段去掉再保存,否则似乎图像是损坏无法打开滴

<?php

    $snapData = $_POST[‘snapData‘];
    $snapData = str_replace(‘data:image/png;base64,‘, ‘‘, $snapData);
    // $snapData = str_replace(‘ ‘, ‘+‘, $snapData);

    $img = base64_decode($snapData);

    $uploadDir = ‘upload/‘;
    $fileName = date(‘YmdHis‘, time()) . uniqid();

    if (!(file_put_contents($uploadDir . $fileName, $img))) {
        echo json_encode(array(‘code‘ => 500, ‘msg‘ => ‘文件上传失败‘));
    } else {
        echo json_encode(array(‘code‘ => 200, ‘msg‘ => ‘文件上传成功‘, ‘path‘ => $uploadDir . $fileName));
    }

?>

完整JS代码

 1 <script type="text/javascript" src="jquery.js"></script>
 2     <script type="text/javascript">
 3     function $(elem) {
 4         return document.querySelector(elem);
 5     }
 6
 7     // 获取媒体方法(旧方法)
 8     navigator.getMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMeddia || navigator.msGetUserMedia;
 9
10     var canvas = $(‘canvas‘),
11         context = canvas.getContext(‘2d‘),
12         video = $(‘video‘),
13         snap = $(‘#snap‘),
14         close = $(‘#close‘),
15         upload = $(‘#upload‘),
16         uploaded = $(‘#uploaded‘),
17         mediaStreamTrack;
18
19     // 获取媒体方法(新方法)
20     // 使用新方法打开摄像头
21     if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
22         navigator.mediaDevices.getUserMedia({
23             video: true,
24             audio: true
25         }).then(function(stream) {
26             console.log(stream);
27
28             mediaStreamTrack = typeof stream.stop === ‘function‘ ? stream : stream.getTracks()[1];
29
30             video.src = (window.URL || window.webkitURL).createObjectURL(stream);
31             video.play();
32         }).catch(function(err) {
33             console.log(err);
34         })
35     }
36     // 使用旧方法打开摄像头
37     else if (navigator.getMedia) {
38         navigator.getMedia({
39             video: true
40         }, function(stream) {
41             mediaStreamTrack = stream.getTracks()[0];
42
43             video.src = (window.URL || window.webkitURL).createObjectURL(stream);
44             video.play();
45         }, function(err) {
46             console.log(err);
47         });
48     }
49
50     // 截取图像
51     snap.addEventListener(‘click‘, function() {
52         context.drawImage(video, 0, 0, 200, 150);
53     }, false);
54
55     // 关闭摄像头
56     close.addEventListener(‘click‘, function() {
57         mediaStreamTrack && mediaStreamTrack.stop();
58     }, false);
59
60     // 上传截取的图像
61     upload.addEventListener(‘click‘, function() {
62         jQuery.post(‘/uploadSnap.php‘, {
63             snapData: canvas.toDataURL(‘image/png‘)
64         }).done(function(rs) {
65             rs = JSON.parse(rs);
66
67             console.log(rs);
68
69             uploaded.src = rs.path;
70         }).fail(function(err) {
71             console.log(err);
72         });
73     }, false);
74
75     </script>

时间: 2024-08-03 19:23:07

JS打开摄像头并截图上传的相关文章

头像截图上传三种方式之一(一个简单易用的flash插件)(asp.net版本)

flash中有版权声明,不适合商业开发.这是官网地址:http://www.hdfu.net/ 本文参考了http://blog.csdn.net/yafei450225664/article/details/12855915     并且加入了自己的解析,以供之后的参考. 官网提供的demo包,包含了php,jsp,asp,aspx的demo. 1.Demo中,avatar.swf是执行上传的flash文件:default.jpg是默认显示的图片:demo.html是demo,可以直接复制里面

如何解决用jquery.uploadify.js进行多文档上传会修改document的title

在dwz框架中使用了jquery.uploadify.js进行多文档上传当打开窗口后会发现document的title被无意之中修改.进行代码调试也没有发现.对swfobject进行研究也没有发现修改title的情况. 只能采用一种方式禁止修改title var oldTitle = document.title; try { document.attachEvent('onpropertychange', function(){ if (document.title != oldTitle )

JS组件系列——Bootstrap文件上传组件:bootstrap fileinput

原文:JS组件系列--Bootstrap文件上传组件:bootstrap fileinput 前言:之前的三篇介绍了下bootstrap table的一些常见用法,发现博主对这种扁平化的风格有点着迷了.前两天做一个excel导入的功能,前端使用原始的input type='file'这种标签,效果不忍直视,于是博主下定决心要找一个好看的上传组件换掉它.既然bootstrap开源,那么社区肯定有很多关于它的组件,肯定也有这种常见的上传组件吧.经过一番查找,功夫不负有心人,还是被博主找到了这个组件:

node.js express fs 获取已上传文件数据格式

{ "fieldName": "photo", "originalFilename": "1395130808991.jpg", "path": "tmpupload/25546-z8u01y.jpg", "headers": { "content-disposition": "form-data; name=\"photo\&

js 实现 input file 文件上传

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script src="js/jquery/jquery-1

spring(java,js,html) 截图上传

html <#-- 上传头像 测试页 使用imgareaselect 插件 --> 最后 上传了这个插件 共学习参考 <link rel="stylesheet" type="text/css" href="${frontRes}/imgareaselect/css/imgareaselect-animated.css" /> <link rel="stylesheet" type="t

ASP.NET MVC 网站开发总结(三) ——图片截图上传

本着简洁直接,我们就直奔主题吧,这里需要使用到一个网页在线截图插件imgareaselect(请自行下载). 前台页面: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="css/imgareaselect-default.css" /> </head> <

Dropzone.js实现文件拖拽上传

dropzone.js是一个开源的JavaScript库,提供 AJAX 异步文件上传功能,支持拖拽文件.支持最大文件大小.支持设置文件类型.支持预览上传结果,不依赖jQuery库. 查看演示 下载源码 使用Dropzone 我们可以建立一个正式的上传form表单,并且给表单一个.dropzone的class. <form id="mydropzone" action="/upload.php" class="dropzone">&l

C#MVC和cropper.js实现剪裁图片ajax上传的弹出层

 首先使用cropper.js插件,能够将剪裁后的图片返回为base64编码,后台根据base64编码解析保存图片. jQuery.cropper: 是一款使用简单且功能强大的图片剪裁jquery插件.该图片剪裁插件支持图片放大缩小,支持图片旋转,支持触摸屏设备,支持canvas,并且支持跨浏览器使用 网站:http://fengyuanchen.github.io/cropper/ 可以自己搜索中文API 前台代码: @{ Layout = null; } <!DOCTYPE html> &