近期项目中有调用本地摄像头拍照然后将拍照结果上传数据库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("图像为空");
}
}