éè¿å¨ä¸ä¸ª canvasï¼ç»å¸ï¼ä¸ç»å video å ç´ åè½ï¼ä½ å¯ä»¥å®æ¶å°æçºµè§é¢æ°æ®æ¥åæåç§è§è§ç¹æå°æ£å¨åç°çè§é¢ç»é¢ä¸ãæ¬æç¨ç¤ºèå¦ä½ä½¿ç¨ JavaScript ä»£ç æ§è¡è²åº¦é®æ§ï¼ä¹è¢«ç§°ä¸ºâç»¿å±ææâï¼ã
ææ¡£å 容以䏿¯ç¨äºæ¸²æè¯¥å 容ç XHTML ææ¡£ã
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style>
body {
background: black;
color: #cccccc;
}
#c2 {
background-image: url(foo.png);
background-repeat: no-repeat;
}
div {
float: left;
border: 1px solid #444444;
padding: 10px;
margin: 10px;
background: #3b3b3b;
}
</style>
<script type="text/javascript;" src="main.js"></script>
</head>
<body onload="processor.doLoad()">
<div>
<video id="video" src="video.ogv" controls="true" />
</div>
<div>
<canvas id="c1" width="160" height="96" />
<canvas id="c2" width="160" height="96" />
</div>
</body>
</html>
ä»è¿é带åºçå ³é®æï¼
canvas
å
ç´ ï¼åå«å¸¦ç ID 为 c1
å c2
ç屿§ãCanvas c1
ç¨äºæ¾ç¤ºåè§é¢çå½å帧ï¼è c2
ç¨äºæ¾ç¤ºæ§è¡äºè²åº¦é®æ§ææåçè§é¢ï¼c2
é¢å
å è½½å°è¢«ç¨äºæ¿æ¢è§é¢ä¸ç»¿å¹ï¼ç»¿è²èæ¯ï¼çéæå¾åãmain.js
çèæ¬å¼å
¥ï¼è¿ä¸ªèæ¬ä½¿ç¨ JavaScript 1.8 ç¹æ§ï¼æä»¥å¨ 22 è¡å¼å
¥èæ¬æ¶å®ç versionï¼çæ¬ï¼æ¯æå®çãmain.js
éç processor.doLoad()
æ¹æ³å¼å§æ§è¡ãmain.js
éç JavaScript 代ç ç±ä¸ä¸ªæ¹æ³ç»æã
å½ XHTML ææ¡£æåå è½½æ¶ doLoad()
æ¹æ³è¢«è°ç¨ãè¿ä¸ªæ¹æ³ç工使¯åå¤è²é®å¤çä»£ç æéçåéï¼å¹¶è®¾ç½®ä¸ä¸ªçå¬äºä»¶ä»¥ä¾¿æä»¬å¯ä»¥çæµç¨æ·ä½æ¶å¼å§ææ¾è§é¢ã
var processor;
processor.doLoad = function doLoad() {
this.video = document.getElementById('video');
this.c1 = document.getElementById('c1');
this.ctx1 = this.c1.getContext('2d');
this.c2 = document.getElementById('c2');
this.ctx2 = this.c2.getContext('2d');
let self = this;
this.video.addEventListener('play', function() {
self.width = self.video.videoWidth / 2;
self.height = self.video.videoHeight / 2;
self.timerCallback();
}, false);
},
è¿æ®µä»£ç æå XHTML ææ¡£ä¸å
³é®å
ç´ çå¼ç¨ï¼å³ video
å
ç´ å两个 canvas
å
ç´ ãå®ä¹è·åäºä¸¤ä¸ª canvas åèªçå¾å½¢ä¸ä¸æå¼ç¨ãè¿äºå°å¨æä»¬çæ£åè²é®æ§å¶ææçæ¶å被ç¨å°ã
ç¶å addEventListener()
被è°ç¨æ¥å¼å§çè§ video
å
ç´ ä»¥ä¾¿æä»¬å¨ç¨æ·æä¸è§é¢ä¸çææ¾æé®æ¶è·å¾éç¥ã为ååºç¨æ·å¼å§åæ¾ï¼è¿æ®µä»£ç è·åäºè§é¢ç宽度åé«åº¦ï¼å¹¶åèªååï¼å½æä»¬æ§è¡è²åº¦é®æ§ææçæ¶åæä»¬å°ååè§é¢ç尺寸ï¼ï¼ç¶åè°ç¨ timerCallback()
æ¹æ³æ¥å¼å§çè§è§é¢ä»¥å计ç®è§è§ææã
计æ¶å¨åè°æåå¨è§é¢å¼å§ææ¾æ¶ï¼å½âææ¾âäºä»¶åçæ¶ï¼è¢«è°ç¨ï¼ç¶åè´è´£è®¾å®èªèº«å®æè¢«è°ç¨ä»¥ä¾¿ä¸ºæ¯ä¸å¸§å¯ç¨é®æ§ææã
processor.timerCallback = function timerCallback() {
if (this.video.paused || this.video.ended) {
return;
}
this.computeFrame();
let self = this;
setTimeout(function() {
self.timerCallback();
}, 0);
},
åè°åç第ä¸ä»¶äºæ æ¯æ£æ¥è§é¢æ¯å¦æ£å¥½å¨ææ¾ï¼å¦æä¸æ¯ï¼åè°ç«å³è¿åå¹¶ä¸ä¼åä»»ä½äºæ ã
ç¶åï¼å¦æè§é¢æ£å¨ææ¾ï¼å®è°ç¨ computeFrame()
æ¹æ³ï¼è¯¥æ¹æ³å¯¹å½åè§é¢å¸§æ§è¡è²åº¦é®æ§ææã
åè°åçæåä¸ä»¶äºæ¯è°ç¨ setTimeout()
æ¥è®¾å®å®èªèº«è¢«å°½å¿«å°å次è°ç¨ãå¨çå®ç¯å¢ä¸ï¼ä½ å¯è½ä¼æ ¹æ®è§é¢ç帧éçæ
嵿¥è®¡åå®ç°è¿ç§è°ç¨ã
䏿¹å±ç¤ºç computeFrame()
æ¹æ³è´è´£çå®è·åä¸å¸§æ°æ®å¹¶æ§è¡è²åº¦é®æ§ææã
processor.computeFrame = function computeFrame() {
this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
let frame = this.ctx1.getImageData(0, 0, this.width, this.height);
let l = frame.data.length / 4;
for (let i = 0; i < l; i++) {
let r = frame.data[i * 4 + 0];
let g = frame.data[i * 4 + 1];
let b = frame.data[i * 4 + 2];
if (g > 100 && r > 100 && b < 43) frame.data[i * 4 + 3] = 0;
}
this.ctx2.putImageData(frame, 0, 0);
return;
};
å½è¿æ®µä¾è¡ç¨åºè¢«è°ç¨æ¶ï¼video å ç´ æ£æ¾ç¤ºææ°çè§é¢æ°æ®å¸§ï¼å°±åè¿æ ·ï¼
å¨ç¬¬ 2 è¡ï¼è§é¢å¸§è¢«å¤å¶å°ç¬¬ä¸ä¸ª canvas çå¾å½¢ä¸ä¸æ ctx1
ä¸ï¼å¹¶æå®äºåæä»¬ä¹åä¿åçå¼ä¸æ ·ç宽度åé«åº¦æ¥ç»å¶ä¸å大å°çå¸§ãæ³¨æè¿ç¹ï¼ä½ å¯ä»¥ç®åå°æ video å
ç´ æ¾å°ä¸ä¸æç drawImage()
æ¹æ³å½ä¸æ¥ç»å¶å½åçè§é¢å¸§å°ä¸ä¸æéãææå¦ä¸ï¼
第 3 è¡éè¿å¨ç¬¬ä¸ä¸ªä¸ä¸æéè°ç¨ getImageData()
æ¹æ³è·åå°è§é¢å½å帧çåå§å¾å½¢æ°æ®çæ·è´ã宿ä¾äºåå§ç 32 ä½åç´ çå¾åæ°æ®ä½¿æä»¬å¯ä»¥ç»§ç»æä½ã第 4 è¡éè¿ç¨å¸§çå¾åæ°æ®çæ»å¤§å°é¤ä»¥åæ¥è®¡ç®å¾åä¸çåç´ æ°ã
ä»ç¬¬ 6 è¡å¼å§ for
å¾ªç¯æ«æå¸§çåç´ ï¼ååºæ¯ä¸ªåç´ ç红ã绿åèçå¼ï¼å¹¶åç¨äºæ£æµç»¿å¹çé¢è®¾çæ°å¯¹æ¯ãå
¶ä¸ç»¿å¹å°ç¨ä» foo.png
导å
¥çéæèæ¯å¾åæ¿æ¢ã
æ¯ä¸ä¸ªï¼æ°å¼ï¼èå´å å¾å°ç被认为æ¯ç»¿å¹ä¸é¨åç帧å¾åæ°æ®éçåç´ å ·æç alpha å¼è¢«æ¿æ¢ä¸ºé¶ï¼ä»¥è¡¨ç¤ºè¯¥åç´ å®å ¨éæãå æ¤ï¼æç»çå¾åéçæ´ä¸ªç»¿å¹çåºå 100% éæï¼äºæ¯å¨ 13 è¡å½å®è¢«ç»å¶å°ç®æ ä¸ä¸æä¸æ¶ï¼æææ¯ä½ä¸ºä¸å±é®ç½©è¦äºéæèæ¯ä¸é¢ã
å½¢æçå¾ååè¿æ ·ï¼
è¿éè§é¢ææ¾è被åå¤å®ç°ï¼æä»¥ä¸å¸§æ¥çä¸å¸§è¢«å¤ç并带æè²é®ææè¢«æ¾ç¤ºåºæ¥ã
åè§RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4