HardBirch

如何使用HTML5实现拍照上传应用

时间:12-03-14 栏目:HTML5移动开发 作者:张飞不张,文采横飞 评论:24 点击: 13,620 次

        在HTML5规范的支持下,WebApp在手机上拍照已经成为可能。在下面,我将讲解Web App如何用手机进行拍照,显示在页面上并上传到服务器。

1、  视频流

        HTML5 The Media Capture API提供了对摄像头的可编程访问,用户可以直接用getUserMedia获得摄像头提供的视频流。我们需要做的是添加一个HTML5的Video标签,并将从摄像头获得视频作为这个标签的输入来源(请注意目前仅Chrome和Opera支持getUserMedia。补充:请使用Opera支持HTML5的新版本,如果是Chrome,版本需为Chrome 18.0.1008+,并使用about:flags来开启WebRTC,请看下图)。

<video id="video" autoplay=""></video>
<script>
var video_element = document.getElementById('video');
if (navigator.getUserMedia) { // opera should use opera.getUserMedia now, chrome use webkitGetUserMedia
         navigator.getUserMedia('video',success, error);
}
function success(stream) {
         video_element.src =stream;
}
</script>
视频流

2、  拍照

        拍照功能,我们采用HTML5的Canvas实时捕获Video标签的内容,Video元素能作为Canvas图像的输入,这一点很棒。主要代码如下:

<script>
         var canvas =document.createElement('canvas');

         var ctx = canvas.getContext('2d');
         var cw = vw;
         var ch = vh;
         ctx.fillStyle = "#ffffff";
         ctx.fillRect(0, 0, cw, ch);
         ctx.drawImage(video_element, 0, 0, vvw,vvh, 0,0, vw,vh);
         document.body.append(canvas);
</script>

3、  图片获取

        下面我们要从Canvas获取图片数据,其核心思路是用canvas的toDataURL将Canvas的数据转换为base64位编码的PNG图像,类似于“data:image/png;base64,xxxxx”的格式。

var imgData =canvas.toDataURL("image/png");

        因为真正图像数据是base64编码逗号之后的部分,所以我们实际服务器处理的图像数据应该是这部分,我们可以用两种办法来获取。

        第一种:是在前端截取22位以后的字符串作为图像数据,例如:

var data = imgData.substr(22);

        如果要在上传前获取图片的大小,可以使用:

var length = atob(data).length;// atob decodes a string of data which has been encoded using base-64 encoding

        第二种:是在后端获取传输的数据后用后台语言截取22位以后的字符串。例如PHP里:

$image = base64_decode( str_replace('data:image/jpeg;base64,', '',$data);

4、  图片上传

        在前端可以使用Ajax将上面获得的图片数据上传到后台脚本。例如使用jQuery时:

$.post('upload.php',{ 'data' : data } );

        在后台我们用PHP脚本接收数据并存储为图片。

function convert_data($data){
    $image = base64_decode( str_replace('data:image/jpeg;base64,', '',$data);
    save_to_file($image);
}
function save_to_file($image){
    $fp = fopen($filename, 'w');
    fwrite($fp, $image);
    fclose($fp);
}

        请注意,以上的解决方案不仅能用于Web App拍照上传,并且你可以实现把Canvas的输出转换为图片上传的功能。这样你可以使用Canvas为用户提供图片编辑,例如裁剪、上色、涂鸦的画板功能,然后把用户编辑完的图片保存到服务器上。

Canvas涂鸦功能

        在HTML5的驱动下,Web App与Native App之间是否还有不可逾越的鸿沟?我将会在3月23日百度开发者大会上现场来解答这个问题,敬请期待。

 

        相关规范:

        The MediaCapture API:http://www.w3.org/TR/media-capture-api/

        Canvas:http://dev.w3.org/html5/2dcontext/

        相关The Media Capture示例:

        Live Photo booth

        Instant Camera

        原创文章,转载请标明出处:蒋宇捷的专栏

声明: 本文由( 张飞不张,文采横飞 )原创编译,转载请保留链接: 如何使用HTML5实现拍照上传应用

如何使用HTML5实现拍照上传应用:目前有24 条留言

  1. 24楼
    wangwei155:

    这个实用,收藏并备用了

    2012-03-15 13:42 [回复]
  2. 23楼
    liuhao1201:

    推荐至首页~

    2012-03-15 18:00 [回复]
  3. 好东西,一定要顶。。。

    2012-03-16 10:20 [回复]
  4. 21楼
    edwardwk1229:

    果断收藏,谢谢了

    2012-03-16 11:02 [回复]
  5. 20楼
    jin123wang:

    这个技术我试过,但是在PC机上无法成功,我用的是最新版本的chrome,if (navigator.getUserMedia) 总是false,不知道怎么回事……

    2012-03-16 21:33 [回复]
  6. 19楼
    zxg1258:

    值得试一试。。。

    2012-03-16 21:37 [回复]
  7. 18楼
    ygvbnh:

    楼主可否分享实例
    或者告诉我们为什么if (navigator.getUserMedia)会返回undefined

    2012-03-19 17:10 [回复]
  8. 17楼
    hfahe:

    [reply]ygvbnh[/reply]
    1、请使用Opera支持HTML5的版本
    2、如果是Chrome,版本为Chrome 18.0.1008+,并使用about:flags来开启WebRTC。

    2012-03-21 12:48 [回复]
  9. 16楼
    hfahe:

    [reply]jin123wang[/reply]
    1、版本为Chrome 18.0.1008+
    2、使用about:flags来开启WebRTC。

    2012-03-21 12:48 [回复]
  10. 15楼
    java67:

    sorry 测试一下 啊

    2012-03-22 10:24 [回复]
  11. 14楼
    leecho571:

    你好,我用的chrome19,但是还是获取不到getUserMedia

    2012-03-22 23:14 [回复]
  12. 13楼
    jin123wang:

    谢谢楼主,开启about:flags启用后测试正常

    2012-03-29 20:09 [回复]
  13. 12楼
    mtmzorro:

    感谢分享那,测试demo 在android平台上 opera mobile 12 支持The Media Capture API,opera mini 7 和 opera mini next均不支持。

    2012-03-30 10:45 [回复]
  14. 11楼
    hfahe:

    [reply]mtmzorro[/reply]
    opera mini是精简版的浏览器,适合低端机。不能作为现代浏览器的代表,现在我理解的opera基本指的是opera mobile。

    2012-03-30 11:20 [回复]
  15. 10楼
    wovfeng:

    不过在手机版的chrome 可以直接用 input type =file 的

    2012-04-09 16:33 [回复]
  16. 9楼
    ydcsh:

    [reply]leecho571[/reply]
    <video id="v" width="940" height="200" autoplay></video>
    <script>
    navigator.webkitGetUserMedia('video', function(stream){
    document.getElementById("v").src = window.webkitURL.createObjectURL(stream);
    }, function(error){
    console.log("不支持媒体流~ ", error);
    });

    单独运行会报错 但是跑在应用里面就可以(我用的tomcat)

    2012-04-09 17:21 [回复]
  17. 8楼
    ydcsh:

    [reply]hfahe[/reply]
    使用about:flags来开启WebRTC
    我花了大半天时间才知道,原来是在地址栏里面输入about:flags 回车,然后找Enable MediaStream. Mac, Windows, Linux, Chrome OS

    2012-04-09 17:26 [回复]
  18. 蒋老师 你好,有个问题想请教,我在mac上通过chorme 调用navigator.webkitGetUserMedia()方法,会启动我的PC上的摄像头,这个没有问题。我想问一下,如何关闭这个视频流呢,我在打开视频后之后,之后关闭当前页签,才能关闭但前的摄像头,我查了很多资料都是告诉我们如何启动camera ,但是没有关闭的,盼复。best regard

    2012-04-22 23:43 [回复]
  19. 6楼
    yangjin123:

    你好看了你文章,然后自己试了一下,结果报错“have no webkitGetUserMedia 或getUserMedia” 我的chrome版本是19

    2012-05-17 10:25 [回复]
  20. 5楼
    lenjent:

    牛人代表,算开眼界了

    2012-05-23 20:53 [回复]
  21. 4楼
    Allenice1:

    程序已经执行success方法了,但是我的camera没有启动。。。。想不明白。。。

    2012-07-02 23:07 [回复]
  22. 我chrome20也不行呢

    2012-07-05 12:49 [回复]
  23. 板凳
    suct_wangjeff:

    一直没有成功~~蒋老师可不可以贴一份直接可以运行的

    2012-07-14 16:04 [回复]
  24. 你好,蒋老师,我用你的第一个例成功了,但第二个不能成功,我用了好几个浏览试,好像都没显示,是怎么回事呀?

    2012-07-30 15:00 [回复]

发表评论


QQ群互动

Linux系统与内核学习群:194051772

WP建站技术学习交流群:194062106

魔豆之路QR

魔豆的Linux内核之路

魔豆的Linux内核之路

优秀工程师当看优秀书籍

优秀程序员,要看优秀书!

赞助商广告

友荐云推荐