近期项目中有调用本地摄像头拍照然后将拍照结果上传数据库blob字段的需求,想了很多的解决方案,由于各种原因都pass掉了,几经周折,最终决定采用jquery webcam这个jquery网络摄像头插件。这里是他的官方网站(应该是吧:) )点点点jquery网络摄像头插件官网。但是各位看官可能会发现,我勒个去,英文的+PHP的+案例挺简单的+上网搜各种搜不全的+...,反正接下来的时间是陷入超级dt的干掉bug死循环,找啊找,编啊编最终凑出来一整套能够正常使用的----我不知道叫啥了现在。好了废话说的够多了,接下来跟各位看官分享整个流程中的关键代码。当然,还是那句话,以上及以下均属个人拙见,欢迎各位看官指正,当然,大神勿喷哦~。
这里不妨啰嗦一句,来解释一下为何将本文分成两部分,且看标题“经过测试的java+jquery+webcam调用本地摄像头拍照,然后将拍照结果上传数据库blob字段功能的实现”:
1、java+jquery+webcam调用本地摄像头拍照;
2、将结果上传至blob;
因为考虑到可能一篇文章篇幅太长,可是单独写成几篇文章不能够系列化的总结,但是对于零零散散的效果不好,所以打算写两部分,还望各位看官理解。至此废话真正结束,开始进入正题。
jquery webcam的介绍大家看上面提供的官网,里面有对它的介绍,这里直接贴源码了,各位看官根据自己的需求改吧:
前端页面:
<label class="layui-form-label" style="width:60px;">尿检照片<br/></label>
<div id="picView" style="width:296px;height:240px;margin-left:73px;">
<div id="webcam" style="width:286px;height:240px"></div>
</div>
前端页面对应js:
//拍照预览 function getPicView(){ var pos = 0, ctx = null, saveCB,w = 320,h= 240, image = []; var canvas = document.createElement("canvas");//创建画布指定宽度和高度 canvas.setAttribute('width', 320); canvas.setAttribute('height', 240); //如果画布成功创建 if (canvas.toDataURL) { ctx = canvas.getContext("2d");//设置画布为2d,未来可能支持3d image = ctx.getImageData(0, 0, 320, 240);//截图320*240,即整个画布作为有效区(cutx?) saveCB = function(data) { var col = data.split(";");//把data切割为数组 var img = image; //绘制图像(这里不是很理解算法) //参数data 只是每行的数据 ,例如320*240 大小的照片,一张完整的照片下来需要240个data,每个data有320个rgb for(var i = 0; i < w; i++) { //转换为十进制 var tmp = parseInt(col[i]); img.data[pos + 0] = (tmp >> 16) & 0xff; img.data[pos + 1] = (tmp >> 8) & 0xff; img.data[pos + 2] = tmp & 0xff; img.data[pos + 3] = 0xff; pos+= 4; } //当绘制320*240像素的图片时发给后端php if (pos == 4 * w * h) { //把图像放到画布上,输出为png格式 ctx.putImageData(img, 0, 0); $.post("***.do?method=picView", {val: "data",w:w,h:h,image: canvas.toDataURL("image/png")},function(){ var imgStr = ""; $("#picView").html(imgStr);//显示拍摄的照片 $("#getPic").off('click');//禁用拍照功能 $("#getPic").addClass('layui-btn-disabled'); }); pos = 0; } }; } else { saveCB = function(data) { image.push(data);//把数据一点点的放入image[] pos+= 4 * w; if (pos == 4 * w * h) { $.ajax({ type: 'POST', url: "***.do?method=picView", data: {val: "pixel",w:w,h:h,image:image.join('|')}, success:function(){ pos = 0, ctx = null, saveCB,w = 320,h= 240, image = []; var imgStr = ""; $("#picView").html(imgStr);//显示拍摄的照片 $("#getPic").off('click');//禁用拍照功能 $("#getPic").addClass('layui-btn-disabled'); } }); pos = 0; } }; } //拍照 $("#webcam").webcam({ width: 280, height: 240, mode: "callback", swffile: "***/webcam/jscam_canvas_only.swf",//自己的路径 onSave: saveCB, onCapture: function () { $("#webcam").css("display", "block"); $("#webcam").fadeOut("fast", function () { $("#webcam").css("opacity", 1); }); webcam.save(); }, debug: function (type, string) { console.log(type + ": " + string); } }); }
/** * @author an * @time 2017年7月30日下午11:14:13 * effect: */ @RequestMapping(params = "method=picView") public void picView(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String savePath = request.getRealPath("/") + "//img//"; File tmp_path = new File(savePath); tmp_path.mkdirs(); //System.out.println("照片数据保存路径:" + savePath); File file_txt = new File(savePath+"001.jpg"); String image = request.getParameter("image");//240 String type = request.getParameter("val");//240 if(null!=image && !"".equals(image)){//防止没有拍照直接保存产生的空指针的错误 String width = request.getParameter("w");//320 String height = request.getParameter("h");//240 int w = Integer.parseInt(width); int h = Integer.parseInt(height); OutputStream out = null; if (null!=type &&"pixel".equals(type)) {//Trident try { BufferedImage bf = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); String[] rows = image.split("\\|"); for (int i = 0; i < rows.length; i++) { String[] col = rows[i].split(";"); for (int j = 0; j < col.length; j++) { int data = Integer.parseInt(col[j], 10); bf.setRGB(j, i, data); } } File picPath = new File(savePath); if (!picPath.exists()) { picPath.mkdirs(); } ImageIO.write(bf, "jpg", file_txt); } catch (Exception e) { e.printStackTrace(); } } else {//WebKit try { byte[] bytes = null; String imageStr = null; //Base64解码并生成图片 //替换头 imageStr = image.replace("data:image/png;base64,", "").trim(); /*if (null != image) { image = image.substring(image.indexOf(",") + 1); }*/ // Base64解码 bytes = new BASE64Decoder().decodeBuffer(imageStr); for (int i = 0; i < bytes.length; ++i) { if (bytes[i] < 0) {// 调整异常数据 bytes[i] += 256; } } // if file doesnt exists, then create it,if file exists ,delete it ,then create it if (!file_txt.exists()) { file_txt.createNewFile(); }else{ file_txt.delete(); file_txt.createNewFile(); } // 生成jpeg图片 out = new FileOutputStream(file_txt.getAbsoluteFile()); out.write(bytes); } catch (Exception e) { e.printStackTrace(); }finally{ if(null!=out){ out.flush(); out.close(); } } } }else{ System.out.println("图像为空"); } }