WebRTC(Web Real-Time Communication,网页实时通信),是一个支持网页浏览器进行实时语音对话或视频对话的API。
视频流
HTML5 的 The Media Capture(媒体捕捉) API 提供了对摄像头的可编程访问,用户可以直接用 getUserMedia (请注意目前仅Chrome和Opera支持)获得摄像头提供的视频流。我们需要做的是添加一个HTML5 的 Video 标签,并将从摄像头获得的视频作为这个标签的输入来源。
打开网页,会提示是否允许视屏设备接入,选择允许。此时,video 标签内将显示动态的摄像视频流。
拍照
拍照是采用HTML5的Canvas功能,实时捕获Video标签的内容,因为Video元素可以作为Canvas图像的输入,所以这一点很好实现。主要代码如下:
//获取图片流
//动态创建画布对象
var canvas = document.getElementById("canvas1");
var context = canvas.getContext('2d');
//将video对象内指定的区域捕捉绘制到画布上指定的区域,可进行不等大不等位的绘制
context.drawImage(video, 0, 0, 330, 212, 0, 0, 120, 80);
//将Canvas的数据转换为base64位编码的PNG图像
var imageData = canvas..toDataURL("image/png");
//截取22位以后的字符串作为图像数据
var imgStr = imageData.substr(22);
//canvas显示图片(canvas显示上传后的图片用)
drawCanvasImage(id, src, width, height) {
var canvas = document.getElementById(id);
var context = canvas.getContext('2d');
var img = new Image();
img.src = src;
mg.onload = function () {
context.drawImage(img, 0, 0, width, height);
};
}
图片上传
前端使用Ajax将图片上传到服务端。
前端代码
function uploadImg() {
//抓取图片并上传图片,返回图片url
var canvas = document.getElementById("canvas1");
var canvas1_1 = document.getElementById("canvas1-1");
var context = canvas.getContext('2d');
var content1_1 = canvas1_1.getContext('2d');
context.drawImage(video, 0, 0, 330, 212, 0, 0, 120, 80);
content1_1.drawImage(video, 0, 0, 330, 212, 0, 0, 720, 480);
//将Canvas的数据转换为base64位编码的PNG图像
var imageData = canvas1_1.toDataURL("image/png");
//截取22位以后的字符串作为图像数据
var imgStr = imageData.substr(22);
//Ajax上传图片
$.ajax({
type: 'post',
url: '/file/uploadBase64Img',
data: {
imgStr: imgStr,
poundLogNo: poundLogNoStr,
uploadType: 1 //上传图片类型 1:称毛重图片 2:称皮重图片
},
cache: false,
dataType: 'json',
success: function (result) {
// console.log("uploadBase64Img", result);
if (result.code == 0) {
//图片上传成功
} else {
layer.alert(result.msg, {icon: 5}); //这时如果你也还想执行yes回调,可以放在第三个参数中。
}
},
error: function (error) {
layer.alert("数据请求异常", {icon: 5}); //这时如果你也还想执行yes回调,可以放在第三个参数中。
}
});
}
后台接口
/**
* Base64字符串转图片 上传
*
* @param imgStr base64字符串
* @param poundLogNo 过磅单号
* @param uploadType 上传图片类型 1:称毛重图片 2:称皮重图片
* @return imgUrl
*/
@RequestMapping(value = "/uploadBase64Img", method = {RequestMethod.POST})
@ResponseBody
public Result uploadBase64Img(String imgStr, String poundLogNo, Integer uploadType) {
if (StringUtils.isEmpty(imgStr)) {
return ResultUtil.error("图像数据为空");
}
if (StringUtil.isEmpty(poundLogNo)) {
return ResultUtil.error("过磅单号不能为空");
}
PoundLog logInDB = poundLogService.findByPoundLogNo(poundLogNo);
if (logInDB == null) {
return ResultUtil.error("找不到您要更新的过磅记录");
}
//构建图片存储路径
StringBuilder filePath = new StringBuilder();
String basePath = DateUtil.getFilePathByDate(systemProperties.getFileLocation() + "/images/upload/");
filePath.append(basePath).append(poundLogNo).append("/");
//生成上传图片名
String fileName = System.currentTimeMillis() + ".jpg";
//base64字符串转图片并保存
String imgLocalPath = ImageUtil.saveBase64Img(imgStr, filePath.toString(), fileName);
if (StringUtils.isEmpty(imgLocalPath)) {
return ResultUtil.error("文件上传失败");
}
//转换成http图片地址
String imgUrl = systemProperties.getLocalhostUrl() + systemProperties.getServerPort() + imgLocalPath.substring(systemProperties.getFileLocation().length());
if (uploadType == null) {
return ResultUtil.error("上传图片类型为空");
}
if (uploadType == UPLOAD_TYPE_GROSS_IMG) {
logInDB.setGrossImgUrl(imgUrl);
} else if (uploadType == UPLOAD_TYPE_TARE_IMG) {
logInDB.setTareImgUrl(imgUrl);
} else {
return ResultUtil.error("未知上传图片类型");
}
int result = poundLogService.update(logInDB);
if (result < 1) {
return ResultUtil.error("图片保存失败");
}
return ResultUtil.success(imgUrl);
}
效果展示
注:以上的解决方案不仅能用于Web App拍照上传,也可以通过Canvas的编辑功能函数提供图片编辑,例如裁剪、上色、涂鸦、圈点等功能,然后把用户编辑完的图片上传保存到服务器上。