視訊流擷取倆張圖片(H5介面)
阿新 • • 發佈:2018-12-17
HTML標籤內容:
//提示框CSS <style type="text/css"> .confirm_ul{list-style:none;margin:0px;padding:0px;width:70%;margin: auto;margin-top: 210%;} .confirm_title{background:#F2F2F2;text-align:left;padding-left:20px;line-height:60px;border:1px solid #999;} .confirm_content{background:#fff;height:80px;line-height:20px;padding:10px;} .confirm_btn-wrap{background:#fff;height:30px;line-height:18px;text-align: right;} .confirm_btn{cursor:pointer;color:#2bd00f;margin-right: 35px;} .confirm_btn-wrap > a:nth-child(1){color: #9c9898;} .dis{display: none;} </style> //視訊介面 <div style="display:none;text-align:center;" id="Living"> <!--人臉框--> <div class="change"> <p></p> <video id="video" width="300" height="250"></video> <p></p> </div> <!--拍照--> <div> <button class="div-buttonClass" id="capture"><span class="div-buttonSpan">點選進行識別</span></button> </div> <!--圖片模組--> <div> <canvas id="canvas1" width="400" height="400" style="display: none;"></canvas> <canvas id="canvas2" width="400" height="400" style="display: none;"></canvas> </div> </div> <!--彈出框-alert--> <div id="alert" class="dis" style="position:absolute;background:rgba(0, 0, 0, 0.58);width:100%;height:220%;top:0;textAlign:center;lineHeight:150px;z-Index:300;fontSize:12px"> <ul class="confirm_ul"> <li id="li2" class="confirm_content" ></li> <li class="confirm_btn-wrap"> <a></a> <a type="button" value="確定" onclick="alertOk()" class="confirm_btn" >確定</a> </li> </ul> </div> <input type="hidden" id="tableId" />
JSCRIPT內容:
//呼叫媒體裝置 function OpenLiving(){ if(!nullValidation()){return false;} let video = document.getElementById('video'); //顯示活體介面 document.getElementById("topLiving").style.display=""; document.getElementById("Living").style.display=""; let canvas1 = document.getElementById('canvas1'); let canvas2 = document.getElementById('canvas2'); let context1 = canvas1.getContext('2d'); let context2 = canvas2.getContext('2d'); if (navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia) { //呼叫使用者媒體裝置, 訪問攝像頭 getUserMedia({video : {width: { min: 1024, ideal: 1280, max: 1920 }, height: { min: 776, ideal: 720, max: 1080 }}}, success, error); } else { tz=true; Alert('不支援訪問使用者媒體',"setOpen.html"); document.getElementById("Living").style.display="none"; } document.getElementById('capture').addEventListener('click', function () { context1.clearRect(0, 0, 400, 400); context1.drawImage(video, 0, 0, 480, 320); sleep(2000); context2.clearRect(0, 0, 400, 400); context2.drawImage(video, 0, 0, 480, 320); }) } //訪問使用者媒體裝置的相容方法 function getUserMedia(constraints, success, error) { if (navigator.mediaDevices.getUserMedia) { //最新的標準API navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error); } else if (navigator.webkitGetUserMedia) { //webkit核心瀏覽器 navigator.webkitGetUserMedia(constraints,success, error) } else if (navigator.mozGetUserMedia) { //firfox瀏覽器 navigator.mozGetUserMedia(constraints, success, error); } else if (navigator.getUserMedia) { //舊版API navigator.getUserMedia(constraints, success, error); } } function success(stream) { //相容webkit核心瀏覽器 let CompatibleURL = window.URL || window.webkitURL; //將視訊流設定為video元素的源 //console.log(stream); mediaStreamTrack = typeof stream.stop === 'function' ? stream : stream.getTracks()[1]; //video.src = CompatibleURL.createObjectURL(stream); video.srcObject = stream; video.play(); } function error(error) { tz=true; Alert('訪問使用者媒體裝置失敗',"setOpen.html"); document.getElementById("Living").style.display="none"; console.log(`訪問使用者媒體裝置失敗${error.name}, ${error.message}`); } //關閉攝像頭 function close() { mediaStreamTrack && mediaStreamTrack.stop(); } //新增時間間隔 function sleep(numberMillis) { var now = new Date(); var exitTime = now.getTime() + numberMillis; while (true) { now = new Date(); if (now.getTime() > exitTime) return; } } //提示框 function Alert(str,goUrl){ $("#alert").removeClass("dis"); $("#li2").html(str); $("#tableId").val(goUrl); } function alertOk(){ $("#alert").addClass("dis"); if(tz){ tz=false; window.location.href=$("#tableId").val(); } }
上傳提交程式碼:
var canvas1 = document.getElementById("canvas1"); var canvas2 = document.getElementById("canvas2"); var dataurl = canvas1.toDataURL("image/png"); var dataur2 = canvas2.toDataURL("image/png"); var videoPhotos1 = encodeURIComponent(dataurl); var videoPhotos2 = encodeURIComponent(dataur2); //關閉相機 close(); parameter["videoPhotos1"]=videoPhotos1; parameter["videoPhotos2"]=videoPhotos2; var requestDate=ajax("xxx",parameter);//需要URL //Alert(JSON.stringify(requestDate)); if(requestDate["code"] != 10000){ }else{ tz=true; Alert("提交成功","##.html"); } //ajax請求(請求路徑url,請求引數json) HJSJ.ajax=function(url,json){ var requestDate=""; $.ajax({ url: url, type:"post", contentType: "application/json", data:json, cache:false, async:false,//同步 false 非同步 true success:function(data){ requestDate=data; }, error:function(jqXHR, textStatus, errorThrown){ var da={}; da["code"]=30001; da["msg"]=jqXHR.status+":"+jqXHR.statusText; requestDate=da; //HJSJ.prompts("error",jqXHR.status+":"+jqXHR.statusText); /* 第一個引數 jqXHR : readyState :當前狀態,0-未初始化,1-正在載入,2-已經載入,3-資料進行互動,4-完成。 status :返回的HTTP狀態碼,比如常見的404,500等錯誤程式碼。 statusText :對應狀態碼的錯誤資訊,比如404錯誤資訊是not found,500是Internal Server Error。 responseText :伺服器響應返回的文字資訊 第二個引數 String textStatus:返回的是字串型別,表示返回的狀態,根據伺服器不同的錯誤可能返回下面這些資訊:"timeout"(超 時), "error"(錯誤), "abort"(中止), "parsererror"(解析錯誤),還有可能返回空值。 第三個引數 String errorThrown:也是字串型別,表示伺服器丟擲返回的錯誤資訊,如果產生的是HTTP錯誤,那麼返回的資訊就是HTTP狀態碼對應的錯誤資訊,比如404的Not Found,500錯誤的Internal Server Error。*/ } }); return requestDate; };
伺服器程式碼:
import java.net.URLDecoder;
import net.sf.json.JSONObject;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
@RequestMapping("/xxx")
@ResponseBody
public Object setOpen(@RequestBody String jsonstring,HttpServletRequest request) {
Map<String, Object> map1 = new HashMap<String, Object>();
Map<String, Object> map2 = new HashMap<String, Object>();
JSONObject parameterObject = JSONObject.fromObject(jsonstring);
String videoPhotos1=parameterObject.optString("videoPhotos1");
String videoPhotos2=parameterObject.optString("videoPhotos2");
//照片存放本地伺服器地址
String webAddress=request.getSession().getServletContext().getRealPath("/");
String url=webAddress+"upLoadPicture/";
map1.put("videoPhotos1",videoPhotos1);
map1.put("videoPhotos2",videoPhotos2);
boolean res = true;
for (int i=1; i<=2; i++) {
String photoBase64 = map1.get("videoPhotos" + i).toString();
// 去除開頭不合理的資料
photoBase64 = photoBase64.substring(30);
photoBase64 = URLDecoder.decode(photoBase64,"UTF-8");
String photoName = String.valueOf(UUID.randomUUID()) + ".png";
String imgUrl = url + photoName;
res= Base64Util.GenerateImage(photoBase64,imgUrl);
if(!res){
map.put("code", 10003);
map.put("msg", "生成圖片失敗");
return map;
}
map2.put("videoPhotos" + i,photoName);
}
//將Base64轉換為圖片
public static boolean GenerateImage(String imgStr,String url){
if (imgStr == null) return false;
BASE64Decoder decoder = new BASE64Decoder();
try
{
//Base64解碼
byte[] b = decoder.decodeBuffer(imgStr);
for(int i=0;i<b.length;++i)
{
if(b[i]<0)
{//調整異常資料
b[i]+=256;
}
}
//生成jpeg圖片
OutputStream out = new FileOutputStream(url);
out.write(b);
out.flush();
out.close();
return true;
}
catch (Exception e)
{
LogUtil.error("error:圖片轉換失敗!"+e.getMessage());
return false;
}
}
}