1、需求
利用电脑、手机摄像头对某零件拍照提取上面的文字(电脑我只用chrome测试过)
2、前端
Ps:id='data'的值就是base64,可通过post请求传到后端
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<html lang="en">
<head>
<title>电脑摄像头拍照&文字识别</title>
</head>
<body>
<table border="1px">
<tr>
<td>
<video id="video" width="320px" height="240px" autoplay="autoplay"></video>
</td>
</tr>
<tr>
<td>
<canvas id="canvas" width="320px" height="240px"></canvas>
</td>
</tr>
<tr>
<td>
<input type="text" value="" id="data" hidden>
<input type="button" title="开启摄像头" value="开启摄像头" onclick="getMedia()"/>
<button type="button" id="snap" onclick="takePhoto()">拍照</button>
<input type="button" title="关闭摄像头" value="关闭摄像头" onclick="closeCamera()"/>
</td>
</tr>
</table>
<script>
//获得video摄像头区域
var buffer;
var video = document.getElementById("video");
function getMedia() {
navigator.mediaDevices.enumerateDevices()
.then(function (devices) {
devices.forEach(function (device) {
//打印电脑上的设备类型、设备名称、设备ID
console.log(device.kind + ":" + device.label + " id=" + device.deviceId);
});
}).catch(function (err) {
console.log(err.name + ":" + err.message);
});
var constraints = {
video: {facingMode: {exact: "environment"}},
audio: false
};
/*
这里介绍新的方法:H5新媒体接口 navigator.mediaDevices.getUserMedia()
这个方法会提示用户是否允许媒体输入,(媒体输入主要包括相机,视频采集设备,屏幕共享服务,麦克风,A/D转换器等)
返回的是一个Promise对象。
如果用户同意使用权限,则会将 MediaStream对象作为resolve()的参数传给then()
如果用户拒绝使用权限,或者请求的媒体资源不可用,则会将 PermissionDeniedError作为reject()的参数传给catch()
*/
var promise = navigator.mediaDevices.getUserMedia(constraints);
promise.then(function (MediaStream) {
buffer = MediaStream;
video.srcObject = MediaStream;
video.play();
}).catch(function (PermissionDeniedError) {
console.log(PermissionDeniedError);
})
}
function takePhoto() {
//获得Canvas对象
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, 320, 240);
var str = canvas.toDataURL("image/jpeg");
document.getElementById("data").value = (str.substr(str.indexOf(",") + 1));
}
function closeCamera() {
buffer && buffer.getTracks()[1].stop();//关闭摄像头
}
</script>
</body>
</html>
Ps:调用手机摄像头拍照上传,仅部分手机浏览器支持,比如QQ、UC;电脑浏览器可选择磁盘路径下的图片
<input type="file" style="text-align: center" onchange="showPic(event)" accept="image/*" multiple>
<script>
var formData;
var xm;
var cnt = 0;
window.onload = function () {
formData = new FormData();
cnt = 0;
};
//图片压缩
function photoCompress(file, callback){
var reader=new FileReader();
reader.readAsDataURL(file);
reader.onload=function(){
var path=this.result;
canvasDataURL(path, callback)
}
}
function canvasDataURL(path, callback){
var img = new Image();
img.src = path;
img.onload = function(){
var that = this;
// 默认按比例压缩
var w = that.width*0.5;
var h = that.height*0.5;
var quality = 0.5; // 默认图片质量为0.7
//生成canvas
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// 创建属性节点
var anw = document.createAttribute("width");
anw.nodeValue = w;
var anh = document.createAttribute("height");
anh.nodeValue = h;
canvas.setAttributeNode(anw);
canvas.setAttributeNode(anh);
ctx.drawImage(that, 0, 0, w, h);
// quality值越小,所绘制出的图像越模糊
var base64 = canvas.toDataURL('image/jpeg', quality);
// 回调函数返回base64的值
callback(base64);
}
}
//图片压缩,并在页面上显示(预览)
function showPic(e) {
var files = e.target.files;
for (var i = 0; i < files.length; i++) {
photoCompress(files[i],function (base64) {
formData.append(xm+cnt, base64.substr(base64.indexOf(",")+1));
cnt++;
});
}
}
function Submit() {
formData.append("xm", xm);
formData.append("num", cnt);
var url="***********";
$.ajax({
url : url,
data : formData,
processData : false,
contentType : false,
dataType: 'json',
type : "POST",
success : function(data){
if(data.msg != "") {
alert(data.msg);
} else {
alert("上传成功");
}
location.reload(true);
}
});
}
</script>
3、后端(百度文字识别建议去百度智能云查看相关文档以及下载所需SDK)
String pic = request.getParameter("pic");
String wlh = request.getParameter("wlh");
Calendar cal = Calendar.getInstance();
int day = cal.get(Calendar.DATE);
int month = cal.get(Calendar.MONTH) + 1;
int year = cal.get(Calendar.YEAR);
net.sf.json.JSONObject jobj = new net.sf.json.JSONObject();
String path = "";
if(System.getProperties().getProperty("os.name").toLowerCase().indexOf("win") != -1) {
path = "F:\\"+year+"\\"+month+"\\"+day;
} else {
path = DomGetServer.getDocBase("/zcjy")+"/"+year+"/"+month+"/"+day;
}
createDir(path);
boolean b = generateImage(pic, path, wlh);
if(b == false) {
msg = "图片上传失败";
} else {
path = path+"/"+wlh+".jpg";
OcrUtil ocrUtil = new OcrUtil();
JSONObject json = ocrUtil.client.handwriting(path, new HashMap<String, String>());
JSONArray res = json.getJSONArray("words_result");
for (int i = 0; i < res.length(); i++) {
JSONObject o = (JSONObject) res.get(i);
msg += o.get("words");
if(i != res.length()-1) {
msg += "/";
}
}
}
public static boolean generateImage(String imgStr,String path,String name) {
//对字节数组字符串进行Base64解码并生成图片
if (imgStr == null) {
return false;
}
BASE64Decoder decoder = new BASE64Decoder();
try {
byte[] b = decoder.decodeBuffer(imgStr);
for(int i=0;i<b.length;++i) {
if(b[i]<0) {
b[i]+=256;
}
}
String imgFilePath = path+"/"+name+".jpg";
OutputStream out = new FileOutputStream(imgFilePath);
out.write(b);
out.flush();
out.close();
return true;
} catch (Exception e) {
System.out.println("===========图片上传异常==========");
e.printStackTrace();
System.out.println("===========图片上传异常==========");
return false;
}
}
/**
* 递归创建文件夹
* @param destDirName
* @return
*/
public static boolean createDir(String destDirName) {
File dir = new File(destDirName);
if (dir.exists()) {
return false;
}
if (dir.mkdirs()) {
return true;
} else {
return false;
}
}
import com.baidu.aip.ocr.AipOcr;
/**
* 百度文字识别
* @author pxChen
* @date 2020/8/24
*/
public class OcrUtil {
//设置APPID/AK/SK
public static final String APP_ID = "2220****";
public static final String API_KEY = "XWoPNcxUgjDQTzzI3kq5****";
public static final String SECRET_KEY = "mRZ0ThKrSAQM4ZGiUGtCYze*********";
public AipOcr client;
public OcrUtil() {
// 初始化一个AipOcr
client = new AipOcr(APP_ID, API_KEY, SECRET_KEY);
// 可选:设置网络连接参数
client.setConnectionTimeoutInMillis(2000);
client.setSocketTimeoutInMillis(60000);
// 可选:设置代理服务器地址, http和socket二选一,或者均不设置
//client.setHttpProxy("proxy_host", proxy_port); // 设置http代理
//client.setSocketProxy("proxy_host", proxy_port); // 设置socket代理
// 可选:设置log4j日志输出格式,若不设置,则使用默认配置
// 也可以直接通过jvm启动参数设置此环境变量
//System.setProperty("aip.log4j.conf", "path/to/your/log4j.properties");
}
}
4、调用电脑摄像头前提条件
通过 MediaDevices.getUserMedia() 获取用户多媒体权限,其只使用关于以下三种情况: localhost 域 开启了; HTTPS 的域 使用; file:/// 协议打开的本地文件
如果在一个 HTTP 站点上,navigator.mediaDevices 的值为 undefined。 想要 HTTP 环境下也能使用和调试 MediaDevices.getUserMedia(),可通过开启 Chrome 的相应参数。
* 在桌面浏览器快捷方式上右键->属性->快捷方式->目标里添加:--unsafely-treat-insecure-origin-as-secure="http://******.com"
与原本内容之间需间隔一个空格,如有多个网址,也以空格隔开
*打开浏览器地址栏,输入chrome://flags/#unsafely-treat-insecure-origin-as-secure,将该 flag 切换成 enable 状态,输入框中填写需要开启的域名,譬如 http://example.com",多个以逗号分隔,重启后生效。