[关闭]
@bornkiller 2014-07-15T10:12:11.000000Z 字数 3621 阅读 5456

浏览器调用摄像头,拍照上传到dropbox

javascript

标题为最近遇到的一个实际要求,题目很简单,做起来挺费心费力。因为兼容性及潜在问题,目前单纯做到desktop chrome only。参考资料多见于 http://www.html5rocks.com/zh/tutorials/,可自行搜索相关内容。

HTML主要部分如下

  1. <div class="container">
  2. <div class="row">
  3. <div class="col-md-6 col-lg-6">
  4. <video id="source" width="100%" height="480" autoplay></video>
  5. <button id="snapTrigger">Snap Photo</button>
  6. <button id="uploadTrigger">Upload Photo</button>
  7. </div>
  8. <div class="col-md-6 col-lg-6">
  9. <canvas id="snapshot" width="600" height="460"></canvas>
  10. </div>
  11. </div>
  12. </div>

浏览器调用摄像头拍照

浏览器调用摄像头需要全新的BOM对象,navigat.webkitGetUserMedia,通过此接口,可以调用摄像头和麦克风,调用时需要用户授权方可开启。

  1. var video = document.querySelector('#source');
  2. var sourceConfig = { "video" : true };
  3. if(navigator.webkitGetUserMedia) {
  4. navigator.webkitGetUserMedia(sourceConfig, function(stream) {
  5. video.src = window.webkitURL.createObjectURL(stream);
  6. video.play();
  7. }, defaultErrHandle);
  8. }

调用很简单,将摄像头捕获的二进制流转换为DomString,再用video节点引用即可,具体接口可自行查询。

  1. var canvas = document.querySelector('#snapshot');
  2. var context = canvas.getContext('2d');
  3. var snapTrigger = document.querySelector('#snapTrigger');
  4. snapTrigger.addEventListener('click',function(e){
  5. context.drawImage(video, 0, 0 ,600,480);
  6. })

canvas画布绘制当前帧的像素信息。

二进制文件转换

前两步顺分顺水,到这一步的时候出现第一次近乎绝望的心情,当JAVASCRIPT一脚踩入二进制的世界,FE的世界观被震撼到。

  1. function canvasToBlob(dataURL){
  2. var BASE64_MARKER = ';base64,';
  3. var parts = dataURL.split(BASE64_MARKER);
  4. var contentType = parts[0].split(':')[1];
  5. var raw = window.atob(parts[1]);
  6. var rawLength = raw.length;
  7. var uInt8Array = new Uint8Array(rawLength);
  8. for (var i = 0; i < rawLength; ++i) {
  9. uInt8Array[i] = raw.charCodeAt(i);
  10. }
  11. return new Blob([uInt8Array], {type: 'imgag/jpeg'});
  12. }

该方法参数为data-url shema,返回值为一个标准 blob 对象。
方法参考了Github.com上封装html5 Filesystem接口开源项目,地址:https://github.com/ebidel/filer.js

Dropbox用户授权

拍照获取二进制对象之后,就需要上传到dropbox,感觉上并不难,dropbox支持HTTP调用,但自己尝试以失败告终,只能通过官方推荐SDK来实现,该SDK功能很强大,但我用到的功能有限。
dropbox.js 地址:https://github.com/dropbox/dropbox-js

  1. var client = new Dropbox.Client({ key: "2oj96m9cxc6psdf" });
  2. client.authenticate(function(error, client) {
  3. if (error) {
  4. defaultErrHandle(error);
  5. }
  6. });
  1. function uploadFile(){
  2. var tmp = canvasToBlob(canvas.toDataURL('image/jpeg'));
  3. if(client.isAuthenticated()){
  4. client.writeFile("profile.jpg", tmp , function(error, stat) {
  5. if (error) {
  6. defaultErrHandle(error); // Something went wrong.
  7. }
  8. });
  9. }
  10. }

通过SDK,可以很便捷的上传任何内容,client.writeFile()方法支持string,File,Blob,ArrayBuffer.

  1. function uploadFile(){
  2. var tmp = canvasToBlob(canvas.toDataURL('image/jpeg'));
  3. var xhr = new XMLHttpRequest();
  4. var data = new FormData();
  5. data.append('profile',tmp,'profile');
  6. xhr.open('POST',
  7. 'https://api-content.dropbox.com/1/files/dropbox/',
  8. true);
  9. xhr.setRequestHeader('Authorization','Bearer ' + window.localStorage.getItem('access_token'));
  10. xhr.send(data);
  11. }

理论上没有问题,但实际上一直在给我返回400 Bad request,多方查阅无法解决,遂只能放弃。

编码有感

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注