摘要:寫在前面感謝各位在前端一直努力奮斗的程序猿們,希望以后的會更美好。寫后呆成魔寫的跟流水賬樣的。最后希望寶強能夠好起來。
寫在前面
感謝各位在前端一直努力奮斗的程序猿們,希望以后的HelloWorld會更美好。
感謝來看看機智的前端童鞋怎么防盜作者的分享
感謝停了一天的網(wǎng)終于恢復(fù)
干貨先來分享2張圖
1)王的憤怒
2) 程序猿的憤怒
通過啟用瀏覽器攝像的方式,把每一幀的圖映射到canvas上,通過比較上一幀與當(dāng)前幀的差異,算出來的差異占的百分比,超過某個百分比就觸發(fā)函數(shù)。
栗子:我搖動我的雙手,兩個幀的手的位置不一樣,從而差異占的比例就挺大的,就觸發(fā)了寫好的回調(diào)函數(shù){
給水杯添加一個動畫 給body更換一個背景顏色
}
程序猿的憤怒是通過在來看看機智的前端童鞋怎么防盜借鑒的代碼實現(xiàn)的,
原作者項目GitHub地址
同時,在不破壞原作者源碼的基礎(chǔ)下,憤怒的程序猿代碼如下:
憤怒的程序猿 水杯您可以嘗試敲打桌面上一幀與這一幀的對比差異檢測到動了一定幅度的截圖
Q:在谷歌瀏覽器上運行的,表示頁面一片空白,啥都沒有,請問這是為什么?
A:通過谷歌的文檔可以得知,這是為了安全性考慮,非 HTTPS 的服務(wù)端請求都不能接入攝像頭,簡單來說,chrome通過文件的方式打開一個html文件,是無法開啟攝像頭的,可以在本地服務(wù)端打開哦!如:localhost
還要注意寫兼容哦!樓主只寫了chrome的
嗨起來程序猿們怎么可能就地止步,讓我們運用代碼,自己來寫一個自動拍照吧!
AV.html
AV.js
(function() { var av = function(option) { option = option || {}; this.op = (function(o) { for(var i in option) { o[i] = option[i]; } return o; }({ style: { width: 320,//視頻 畫布 寬 height: 240//高 }, deg: 0.12,//靈敏度 觸發(fā)動作幅度 die: 500,//dwon機時間,觸發(fā)事件后500ms內(nèi)不觸發(fā) delta:300,//取幀間隔 300ms 獲取一次視頻幀 sw:true//開關(guān),默認為開 })); this.initEm(); this.initMedia(); this.initCanvas(); this.switchAV(); } var avpro = av.prototype; //初始化基礎(chǔ)元素 avpro.initEm = function() { //video元素 this.video = document.querySelector(this.op.el || "video"); this.video.setAttribute("autoplay", ""); this.video.style.objectFit = "fill"; //初始化canvas元素 var canvas = document.createElement("canvas"); canvas.style.display = "none"; canvas.style.backgroundColor = this.video.style.backgroundColor = "grey"; canvas.style.width = this.video.style.width = (this.w = canvas.width = this.op.style.width) + "px"; canvas.style.height = this.video.style.height = (this.h = canvas.height = this.op.style.height) + "px"; //動作畫布克隆,映射視頻 ac 動作Action 便于記憶 var acCanvas = canvas.cloneNode(true); //對比畫布克隆,比較差異 bw 表示黑白 便于記憶 var bwCanvas = canvas.cloneNode(true); //清除原體釋放資源 canvas = null; //添加至頁面 document.body.appendChild(acCanvas); document.body.appendChild(bwCanvas); this.canvas = acCanvas; this.acCanvas = acCanvas.getContext("2d"); this.bwCanvas = bwCanvas.getContext("2d"); } //初始化攝像頭 avpro.initMedia = function() { var tv = this.video; navigator.getUserMedia || navigator.webkitGetUserMedia //ie chrome ({ video: true }, function(se) { tv.src = window.URL.createObjectURL(se); tv.play(); }, function(err) { console.log("err:" + err); }); } //初始化畫布,幀數(shù) avpro.initCanvas = function() { //將第二個畫布混合模式設(shè)為“差異” this.bwCanvas.globalCompositeOperation = "difference"; // 前一幀 當(dāng)前幀 差異幀 this.preFrame = this.curFrame = this.diffFrame = null; } //開始AV avpro.startAv = function() { var tv = this; var call = arguments.callee; tv.zt = setTimeout(function() { tv.avSaveFrame(); tv.renderDiff(); setTimeout(function() { if(tv.calcDiff() >= tv.op.deg) { //觸發(fā)事件 tv.handel(); } }, 16.7); call.call(tv); },tv.op.delta); } //設(shè)置開關(guān) 和 回調(diào)函數(shù) avpro.switchAV = function(sw,fn){ if(sw == undefined ? this.op.sw:sw){ this.startAv(); }else{ this.stopAv(); } fn && (this.op.fn = fn); } avpro.stopAv = function(){ this.zt && clearTimeout(this.zt); } //觸發(fā)事件 avpro.handel = function() { var tv = this; if(tv.t) { return; } console.log(tv.fn); tv.op.fn && tv.fn(tv.curFrame); tv.t = setTimeout(function() { tv.t = null; },tv.op.die); } avpro.getCurFrame = function(){ return this.curFrame; } //捕獲并保存幀 avpro.avSaveFrame = function() { //幀替換 this.preFrame = this.curFrame; this.acCanvas.drawImage(this.video, 0, 0, this.w, this.h); //轉(zhuǎn)為base64并保存當(dāng)前幀 this.curFrame = this.canvas.toDataURL(); } //繪制base64圖像到畫布上 avpro.drawImg = function(src, ctx) { ctx = ctx || this.bwCanvas; var img = new Image(); img.src = src; ctx.drawImage(img, 0, 0 ,this.w, this.h); } //渲染前后兩幀差異 avpro.renderDiff = function() { if(!this.preFrame || !this.curFrame) return; this.bwCanvas.clearRect(0, 0, this.w, this.h); this.drawImg(this.preFrame); this.drawImg(this.curFrame); //捕獲差異幀的imageData對象 this.diffFrame = this.bwCanvas.getImageData(0, 0, this.w, this.h); } //計算差異 avpro.calcDiff = function() { if(!this.diffFrame) return 0; var cache = arguments.callee, count = 0; cache.total = cache.total || 0; //整個畫布都是白色時所有像素的值的總和 for(var i = 0, l = this.diffFrame.width * this.diffFrame.height * 4; i < l; i += 4) { count += this.diffFrame.data[i] + this.diffFrame.data[i + 1] + this.diffFrame.data[i + 2]; if(!cache.isLoopEver) { //只需在第一次循環(huán)里執(zhí)行 cache.total += 255 * 3; //單個白色像素值 } } cache.isLoopEver = true; count *= 3; //亮度放大 //返回“差異畫布高亮部分像素總值”占“畫布全亮情況像素總值”的比例 return Number(count / cache.total).toFixed(2); } var nav = null; window.Av = function(op) { return nav || (nav = new av(op)); }; }())遺言
寫前圣成佛:感覺自己馬上要寫出一篇無與倫比的文章。
寫后呆成魔:寫的跟流水賬樣的。
最后希望寶強能夠好起來。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/50009.html
摘要:寫在前面感謝各位在前端一直努力奮斗的程序猿們,希望以后的會更美好。寫后呆成魔寫的跟流水賬樣的。最后希望寶強能夠好起來。 寫在前面 感謝各位在前端一直努力奮斗的程序猿們,希望以后的HelloWorld會更美好。 感謝來看看機智的前端童鞋怎么防盜作者的分享 感謝停了一天的網(wǎng)終于恢復(fù) 干貨 先來分享2張圖1)王的憤怒showImg(https://segmentfault.com/img/b...
摘要:寫在前面感謝各位在前端一直努力奮斗的程序猿們,希望以后的會更美好。寫后呆成魔寫的跟流水賬樣的。最后希望寶強能夠好起來。 寫在前面 感謝各位在前端一直努力奮斗的程序猿們,希望以后的HelloWorld會更美好。 感謝來看看機智的前端童鞋怎么防盜作者的分享 感謝停了一天的網(wǎng)終于恢復(fù) 干貨 先來分享2張圖1)王的憤怒showImg(https://segmentfault.com/img/b...
上傳視頻要提供視頻封面(視頻封面必填),這是在開發(fā)中實際問題。封面可以用戶自己制作并上傳,但這樣脫離網(wǎng)站,體驗不好,常見的處理方案就是用戶未選擇或上傳封面時,自動截取視頻第一幀作為封面,但這樣并不友好。因此考慮視頻上傳后,在播放中由人員自行截取畫面作為視頻封面。 簡單效果如圖: 前端代碼如下: <template> <div> <videosrc=&...
摘要:月日,央視秘密大改造節(jié)目展示了一項終極挑戰(zhàn),為一位視障人士改造房屋。比起接受精心的照顧,視障人士更愿意接受能讓他們回歸正常世界的工具。 7月28日,央視《秘密大改造》節(jié)目展示了一項終極挑戰(zhàn),為一位視障人士改造房屋。阿里云IoT工程師代立晨志愿參與挑戰(zhàn),他在兩周時間里,通過大量的傳感設(shè)備、網(wǎng)絡(luò)設(shè)置、傳輸指令,讓這間69平米的房子仿佛被賦予生命,它能聽會看,可以認識主人、陪伴主人、照顧主人...
閱讀 3925·2021-10-12 10:12
閱讀 2886·2021-09-10 11:18
閱讀 3673·2019-08-30 15:54
閱讀 2808·2019-08-30 15:53
閱讀 638·2019-08-30 13:54
閱讀 965·2019-08-30 13:21
閱讀 2260·2019-08-30 12:57
閱讀 1687·2019-08-30 11:10