最近一个需求就是做一个二维码扫描的功能,但是又不想使用安卓app的方式实现,百度了一下貌似html5可以实现。
项目使用环境以及工具:
eclipse,jdk1.7,struts2,html5,jquery,qrcode
引用
html5技术支持webapp在手机上拍照,显示在页面上并上传到服务器。这是手机微博应用中常见的功能,当然你也可以在其它类型应用中适当使用此技术。
这个功能不但手机端可以实现pc端也可以很好的实现,这个应用接口技术就是getusermedia api,它能让应用开发者访问用户的摄像头或内置相机。下面就让我展示一下如何通过浏览器来访问你的摄像头,并提取截屏图形。
一、视频流
html5 的 the media capture(媒体捕捉) api 提供了对摄像头的可编程访问,用户可以直接用 getusermedia (请注意目前仅chrome和opera支持)获得摄像头提供的视频流。我们需要做的是添加一个html5 的 video 标签,并将从摄像头获得的视频作为这个标签的输入来源。
二、拍照
拍照是采用html5的canvas功能,实时捕获video标签的内容,因为video元素可以作为canvas图像的输入,所以这一点很好实现。
三、 获取图片
从canvas获取图片数据的核心思路是用canvas的todataurl将canvas的数据转换为base64位编码的png图像,类似于“data:image/png;base64,xxxxx”的格式。
var imgdata=canvas.todataurl(“image/png”);
这样,imgdata变量就存储了一长串的字符数据内容,表示的就是一个png图像的base64编码。因为真正的图像数据是base64编码逗号之后的部分,所以要让实际服务器接收的图像数据应该是这部分,我们可以用两种办法来获取。
第一种:是在前端截取22位以后的字符串作为图像数据,例如:
var data=imgdata.substr(22);
第二种:就是替换;前面的部分为"";
var image = canvas.todataurl("image/png").replace("data:image/png;base64,", "");
反正不管如何实现,能获取到图片流即可、
四、上传图片并解析
使用 setinterval定时上传到项目后台使用开源qrcode.jar 解析图片获取二维码信息。
前台部分代码:
javascript code
<a target="_blank" href="http://bbs.csdn.net/topics/391982089#clipboardwindow">?</a>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<code><video id=</code><code>"video"</code><code>></code>
<code><script></code>
<code> </code><code>var</code> <code>flag = </code><code>true</code><code>;</code>
<code> </code><code>window.addeventlistener(</code><code>"domcontentloaded"</code><code>, </code><code>function</code> <code>() {</code>
<code> </code><code>var</code> <code>video = document.getelementbyid(</code><code>"video"</code><code>), canvas, context;</code>
<code> </code><code>try</code> <code>{</code>
<code> </code><code>canvas = document.createelement(</code><code>"canvas"</code><code>);</code>
<code> </code><code>canvas.width = 600;</code>
<code> </code><code>canvas.height = 600;</code>
<code> </code><code>context = canvas.getcontext(</code><code>"2d"</code><code>);</code>
<code> </code><code>} </code><code>catch</code> <code>(e) { alert(</code><code>"not support canvas!"</code><code>); </code><code>return</code><code>; }</code>
<code> </code><code>navigator.getusermedia = navigator.getusermedia || navigator.webkitgetusermedia || navigator.mozgetusermedia || navigator.msgetusermedia;</code>
<code> </code><code>if</code> <code>(navigator.getusermedia)</code>
<code> </code><code>navigator.getusermedia(</code>
<code> </code><code>{ </code><code>"video"</code><code>: </code><code>true</code> <code>},</code>
<code> </code><code>function</code> <code>(stream) {</code>
<code> </code><code>if</code> <code>(video.mozsrcobject !== undefined)video.mozsrcobject = stream;</code>
<code> </code><code>else</code> <code>video.src = ((window.url || window.webkiturl || window.mozurl || window.msurl) && window.url.createobjecturl(stream)) || stream; </code>
<code> </code><code>video.play();</code>
<code> </code><code>},</code>
<code> </code><code>function</code> <code>(error) {</code>
<code> </code><code>alert(</code><code>"请检查是否开启摄像头"</code><code>);</code>
<code> </code><code>flag = </code><code>false</code><code>;</code>
<code> </code><code>}</code>
<code> </code><code>);</code>
<code> </code><code>else</code> <code>alert(</code><code>"native device media streaming (getusermedia) not supported in this browser"</code><code>);</code>
<code> </code>
<code> </code><code>setinterval(</code><code>function</code> <code>() {</code>
<code> </code><code>if</code><code>(!flag){</code>
<code> </code><code>return</code><code>;</code>
<code> </code><code>context.drawimage(video, 0, 0, canvas.width = video.videowidth, canvas.height = video.videoheight);</code>
<code> </code><code>var</code> <code>image = canvas.todataurl(</code><code>"image/png"</code><code>).replace(</code><code>"data:image/png;base64,"</code><code>, </code><code>""</code><code>); </code>
<code> </code><code>$.ajax({</code>
<code> </code><code>url : </code><code>'qrcodeaction_decoderqrcode.action'</code><code>,</code>
<code> </code><code>async : </code><code>false</code><code>,</code>
<code> </code><code>type : </code><code>'post'</code><code>,</code>
<code> </code><code>data : {</code>
<code> </code><code>'time'</code> <code>: (</code><code>new</code> <code>date()).tostring(),</code>
<code> </code><code>'img'</code> <code>: image</code>
<code> </code><code>},</code>
<code> </code><code>success : </code><code>function</code><code>(result) {</code>
<code> </code>
<code> </code><code>});</code>
<code> </code><code>}, 5000);</code>
<code> </code><code>}, </code><code>false</code><code>);</code>
<code> </code><code></script> </code>
后台部分代码:
java code
<code>/**</code>
<code> </code><code>* 解析二维码</code>
<code> </code><code>*/</code>
<code> </code><code>public</code> <code>string decoderqrcode(){</code>
<code> </code><code>try</code> <code>{</code>
<code> </code><code>string realpath = servletactioncontext.getservletcontext().getrealpath(</code><code>"/file"</code><code>);</code>
<code> </code><code>simpledateformat sdf = </code><code>new</code> <code>simpledateformat(</code><code>"yyyymmddhhmmss"</code><code>);</code>
<code> </code><code>string imgname = sdf.format(</code><code>new</code> <code>date()) + </code><code>".png"</code><code>;</code>
<code> </code><code>string filepath = realpath+constants.sf_file_separator+imgname;</code>
<code> </code><code>outputstream out = </code><code>new</code> <code>fileoutputstream(filepath);</code>
<code> </code><code>qrcode.generateimage(img,out);</code><code>//生成图片</code>
<code> </code><code>message = qrcode.decoderqrcode(filepath);</code>
<code> </code><code>} </code><code>catch</code> <code>(exception e) {</code>
<code> </code><code>e.printstacktrace();</code>
<code> </code><code>return</code> <code>action.success;</code>
<code> </code><code>}</code>
调用电脑拍摄一定要允许操作。现在只需要html5的画布技术和javascript,我们就能简单快速的操作用户的摄像头。手机不仅可以调用摄像头扫描,pc不仅仅能访问摄像头,而且利用html5强大的画布技术,我们可以给图片上加入各种迷人的滤镜效果。现在,在浏览器里用自己的摄像头给自己拍张照片吧!
有些手机可能无法调出摄像头,那就赶紧换手机吧,别out了。