TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
最近一个需求就是做一个二维码扫描的功能,但是又不想使用安卓APP的方式实现,百度了一下貌似HTML5可以实现。" U/ m/ o, [. i) p; Y+ @" f& u# E! B
! q! ]4 D& T& K) x* L# v1 @6 h6 h' @7 r* B' H
项目使用环境以及工具:+ H8 x0 }5 U6 t: K
: c* v" v; Y0 L3 M
Eclipse,JDK1.7,struts2,HTML5,Jquery,QRCode: s0 h. [) a( q+ _0 F
HTML5技术支持WebApp在手机上拍照,显示在页面上并上传到服务器。这是手机微博应用中常见的功能,当然你也可以在其它类型应用中适当使用此技术。 $ p* W: I7 Z* q0 Y( L: _1 n4 g: p- m# b
这个功能不但手机端可以实现PC端也可以很好的实现,这个应用接口技术就是getUserMedia API,它能让应用开发者访问用户的摄像头或内置相机。下面就让我展示一下如何通过浏览器来访问你的摄像头,并提取截屏图形。
( k! p, ~; ?( f6 U) u
$ j7 r2 v) z' h0 F2 l一、视频流 & B1 K# q, k& E4 z K9 r2 P
2 y% F. c5 X. T. h1 K1 f# b HTML5 的 The Media Capture(媒体捕捉) API 提供了对摄像头的可编程访问,用户可以直接用 getUserMedia (请注意目前仅Chrome和Opera支持)获得摄像头提供的视频流。我们需要做的是添加一个HTML5 的 Video 标签,并将从摄像头获得的视频作为这个标签的输入来源。
" R. Y$ s6 m6 O* a+ `7 q& w) Y4 [5 N" k, l7 Y
二、拍照6 \: w- y$ V/ {5 T% z4 j
0 V# q5 r, X) U5 D+ J拍照是采用HTML5的Canvas功能,实时捕获Video标签的内容,因为Video元素可以作为Canvas图像的输入,所以这一点很好实现。" R' c1 P# ?) E7 W# a& Y9 C
# L* i/ E/ Q9 Z: r/ S. E9 y三、 获取图片
* A9 d3 A2 p$ Q3 j' F1 i$ _* J) H r! R P% }/ W# f6 _% m, ]
从Canvas获取图片数据的核心思路是用canvas的toDataURL将Canvas的数据转换为base64位编码的PNG图像,类似于“data:image/png;base64,xxxxx”的格式。) i7 y y& ~3 u$ i1 d
4 i. [# C) I: K u0 D% q# jvar imgData=canvas.toDataURL(“image/png”);2 {: [/ R! J/ a! N
3 w- a4 v4 n: R+ e7 }1 `
这样,imgData变量就存储了一长串的字符数据内容,表示的就是一个PNG图像的base64编码。因为真正的图像数据是base64编码逗号之后的部分,所以要让实际服务器接收的图像数据应该是这部分,我们可以用两种办法来获取。
% g# J. W: e; h9 O 第一种:是在前端截取22位以后的字符串作为图像数据,例如:
% d1 a+ q" _1 Z; K) P7 ^1 J7 I/ ]/ u/ K, }1 w4 O
var data=imgData.substr(22);* ^. g3 o) o3 ~) J7 q/ m" w7 Q
+ ^; d+ {* e, U 第二种:就是替换;前面的部分为"";
1 J* T& R T; |& T' z+ M l7 j9 q$ F
var image = canvas.toDataURL("image/png").replace("data:image/png;base64,", "");
) j$ v, j3 x2 g: q7 N2 Z7 v3 H! e* x" _$ ^# w( b
反正不管如何实现,能获取到图片流即可、
& n7 j1 I. F1 f h9 e$ m3 R- y9 k$ a: B/ V w+ @7 x' K- h, Q& T
四、上传图片并解析
5 K) N0 f5 U5 m) z5 G; e, j/ A2 r) ~$ M3 c: ^# R. E9 p
使用 setInterval定时上传到项目后台使用开源QRCode.jar 解析图片获取二维码信息。. R% J9 ^& g! ^
7 }7 N: Q+ k& F: G9 R' Q
前台部分代码:
: T% w2 S# Q8 I0 e+ g- <video id="video">
& a& l6 h* y/ u: b9 V; j0 A - <script>
& f# r, p! S, H( ^% [ - var flag = true;- G" T- C) n4 U4 t: |) L7 x
- window.addEventListener("DOMContentLoaded", function () {
8 }* d% R; q% P; @6 a - var video = document.getElementById("video"), canvas, context;; m2 Z8 J6 o4 X8 N
- try {
9 Z. Z# Y0 ?* P4 ~2 @: Z! S - canvas = document.createElement("canvas");
% L4 H g9 ~7 j, {7 @ - canvas.width = 600;% a/ V/ s! H1 H
- canvas.height = 600;
8 H: O3 o: i& G - context = canvas.getContext("2d");
8 F' X9 c0 J" X7 {9 _# [9 R - } catch (e) { alert("not support canvas!"); return; }1 O' }8 |: w) D$ Q Y
- navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;: @( s- t% F2 _: X6 X: P
- & r( S9 O' p V, G( E( K
- if (navigator.getUserMedia)
: h! l* G- f5 q( R - navigator.getUserMedia(% {$ C& V" `( r, _+ j* e8 q5 ]
- { "video": true },
# c! j: `- y( ]0 F# F/ G - function (stream) {
- O; e( m* W8 [/ o& q9 T - if (video.mozSrcObject !== undefined)video.mozSrcObject = stream;$ `$ r7 w, P5 l
- else video.src = ((window.URL || window.webkitURL || window.mozURL || window.msURL) && window.URL.createObjectURL(stream)) || stream; , S$ X; B& v9 V
- video.play();
Q! Y* v2 \$ \6 O- \ - },
; o3 r5 s* V. I* ^ - function (error) {
: k7 V8 ^) w ^: f0 t7 Z - alert("请检查是否开启摄像头");
; u9 o, }9 u! K# C1 Q' n - flag = false;) L3 {- H6 o& J" x/ z
- }
7 j4 M* W3 H7 h+ G+ w/ o' V - );. \2 s# m9 t X" _8 k/ A- ~
- else alert("Native device media streaming (getUserMedia) not supported in this browser");. U) w$ v1 g0 [& j g5 l
-
4 ~# |- V6 i6 h" t d# j; g - setInterval(function () {$ _& F4 ~5 N, L& q+ { K& ~
- if(!flag){
4 k" X _6 {' v9 | - return;3 g, i' Q& x( D+ I- Y' l* f( A" y% j
- }
0 r" H1 \8 z3 D( u, A* f - context.drawImage(video, 0, 0, canvas.width = video.videoWidth, canvas.height = video.videoHeight);
/ ?; d W8 ^6 K4 ~! g1 V# J - var image = canvas.toDataURL("image/png").replace("data:image/png;base64,", ""); 1 u! ]( t! O5 Y; u0 r' d9 ~, Q" V9 E
- $.ajax({
5 b% d! s2 R9 g" b7 n1 S7 z+ g - url : 'qRCodeAction_decoderQRCode.action',
; F! _$ o, m7 ~' w - async : false,
w3 {" g) A& L5 E1 D5 r - type : 'post',
/ m5 Y( m7 ?& _) S% |3 w - data : { R, e P3 `8 \; R! |6 {& K) S* L7 C
- 'time' : (new Date()).toString(),
! J* G* v7 W$ l" N: L. y: u% G6 g - 'img' : image' K/ p$ B1 |, Z, T
- },
/ I5 d/ X; \0 v. h! t3 B - success : function(result) {
% ^# g. }( F% X8 P& U - 0 S. Q/ t9 L; M: S% a: T X% ^$ g( q
- },& [6 Y% @2 A: D. ~
- });
7 Q' ]6 F8 C- x - }, 5000);
3 R; k+ a* X9 ]* C2 B8 I - }, false);4 R3 @3 K, y, q2 L( w$ N& s' a
- </script>
复制代码
0 ^; W0 F# ^+ M9 `5 ^后台部分代码:
5 A/ s) D% n; Y7 U- /**+ V$ ~" Q1 T, E; E& J3 h c, z
- * 解析二维码
3 p* s9 H1 p9 ^8 X - * @Author 张志朋
8 M6 ^. v' }$ r1 C& D$ Z- Y - * @return String$ B& w4 p. i/ H" ?5 g, \! j) q
- * @Date 2016年7月9日
$ K2 u! `( b) Z1 \ - * 更新日志2 v& v; [+ I `3 z) I
- * 2016年7月9日 张志朋 首次创建+ ] r: T' H% w4 ]7 S
- *
* G/ w0 n) r a - */
, x" z- O V% D9 X - public String decoderQRCode(){
3 \0 ?9 l% L/ a - try {5 ~0 c' y5 i: R/ c
- String realpath = ServletActionContext.getServletContext().getRealPath("/file");' x' P! J3 A* v- r9 n6 u
- SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
# J) q: e; f2 u o+ o* F3 Z - String imgName = sdf.format(new Date()) + ".png";! v8 b7 w( y% B5 ~5 Q
- String filePath = realpath+Constants.SF_FILE_SEPARATOR+imgName;
5 f; F+ X, N: e: X) V - OutputStream out = new FileOutputStream(filePath);; L' g. P/ ~: u
- QRCode.GenerateImage(img,out);//生成图片
1 ~" {! y/ {" h - message = QRCode.decoderQRCode(filePath);
8 `: t, v. x( k [ - } catch (Exception e) {
. b" |' `2 Y8 \; k$ H& L% J8 N - e.printStackTrace();
" w+ \7 @9 b S# d - }
# w! B" A7 S5 u0 u, W, V2 Q - return Action.SUCCESS;
4 z* Y4 J6 Z. U2 \! H - }
复制代码 ) \& o2 R4 c' w6 U' ?! x$ Y
- W+ m" h7 Z6 P' W! G i调用电脑拍摄一定要允许操作。现在只需要HTML5的画布技术和javaScript,我们就能简单快速的操作用户的摄像头。手机不仅可以调用摄像头扫描,PC不仅仅能访问摄像头,而且利用HTML5强大的画布技术,我们可以给图片上加入各种迷人的滤镜效果。现在,在浏览器里用自己的摄像头给自己拍张照片吧!4 a# H4 \$ C6 r: y2 y
+ J5 c/ u( {, w, [$ T+ C, `
( Z) @7 e8 G! r' K. x$ D ~
$ K7 T9 t: k4 ~4 g
1 Z$ r' G) T$ _2 F+ P" U! J* d
4 Z- l6 V* j: n0 `有些手机可能无法调出摄像头,那就赶紧换手机吧,别out了。. N+ d% Z( m$ V
1 M, A( k# \% \3 T# |附上演示地址:http://monitor.52itstyle.com/% m W' m1 g# z- I
! N7 |! p3 V; G+ _" e$ |项目源码下载地址5 N7 [6 @5 V: A7 `1 d+ C, a
9 P, B1 d2 s+ l1 f+ b
5 Q: G9 B8 M9 ^$ N. [
提取码:/ R1 W5 \& {+ W& u, g
, g4 s9 t- E& O. @
) U3 J+ K5 O- C7 o" R5 ?' Z
8 S# h4 Y2 z o2 b
/ @' T3 \/ P6 W |
|