>웹 프론트엔드 >H5 튜토리얼 >HTML5: Canvas를 사용하여 실시간으로 비디오 처리

HTML5: Canvas를 사용하여 실시간으로 비디오 처리

高洛峰
高洛峰원래의
2018-05-28 17:58:126174검색

문서 내용

이 글에 사용된 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;
}
p {
float: left;
border :1px solid #444444;
padding:10px;
margin: 10px;
background:#3B3B3B;
}
</style>
<script type="text/javascript;version=1.8" src="main.js"></script>
</head>

<body onload="processor.doLoad()">
<p>
<video id="video" src="video.ogv" controls="true"/>
</p>
<p>
<canvas id="c1" width="160" height="96"/>
<canvas id="c2" width="160" height="96"/>
</p>
</body>
</html>

위 코드의 주요 부분은 다음과 같습니다.

1. 각각 ID가 c1과 c2인 두 개의 캔버스 요소를 만듭니다. c1은 현재 프레임의 원본 비디오를 표시하는 데 사용되며, c2는 크로마 키 특수 효과를 수행한 후 비디오를 표시하는 데 사용됩니다. c2에는 비디오의 배경색 부분을 대체하는 데 사용되는 정적 이미지가 미리 로드됩니다.

2. JavaScript 코드는 main.js 파일에서 가져옵니다. 이 스크립트는 JavaScript 1.8의 기능을 사용하므로 스크립트를 가져올 때 버전이 22행에 지정됩니다.

3. 웹페이지가 로드되면 main.js의 processor.doLoad() 메서드가 실행됩니다.

JavaScript 코드

main.js의 JS 코드에는 세 가지 메서드가 포함되어 있습니다.

크로마 키 초기화

XHTML 문서가 처음 로드될 때 doLoad() 메서드가 호출됩니다. 이 방법의 목적은 크로마키 처리 코드에 필요한 변수를 준비하고 사용자가 비디오 재생을 시작하는 시점을 감지할 수 있도록 이벤트 리스너를 설정하는 것입니다.

doLoad: function() {
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 요소와 두 개의 캔버스 요소에 대한 참조를 가져오고 두 캔버스의 그래픽 컨텍스트에 대한 참조도 가져옵니다. 이는 크로마 키잉 효과를 구현할 때 사용됩니다.

addEventListener()는 비디오 요소를 수신하고 사용자가 비디오의 재생 버튼을 누르면 호출됩니다. 사용자 재생을 처리하기 위해 이 코드는 비디오의 너비와 높이를 가져와 절반으로 줄인 다음(크로마 키잉 효과를 수행할 때 비디오 크기를 절반으로 줄입니다), 타이머Callback() 메서드를 호출하여 비디오 캡처를 시작합니다. 및 시각 효과 계산.

타이머 콜백

타이머 콜백 함수는 동영상 재생이 시작될 때("재생" 이벤트가 발생할 때) 호출되며, 그런 다음 동영상의 키잉 특수 효과를 구현하기 위해 자체 주기적인 호출을 담당합니다. 비디오의 각 프레임.

timerCallback: function() {
if (this.video.paused || this.video.ended) {
return;
}
this.computeFrame();
let self = this;
setTimeout(function () {
self.timerCallback();
}, 0);
},

콜백 함수는 먼저 동영상이 재생 중인지 확인하고 그렇지 않은 경우 콜백 함수는 아무 작업도 수행하지 않고 즉시 반환합니다.

그런 다음 현재 비디오 프레임에 크로마 키잉 특수 효과를 수행하는 ComputeFrame() 메서드를 호출합니다.

콜백 함수가 마지막으로 하는 일은 setTimeout()을 호출하여 최대한 빨리 다시 호출할 수 있도록 하는 것입니다. 실제 환경에서는 비디오의 프레임 속도에 따라 호출 빈도를 설정할 수 있습니다.

비디오 프레임 데이터 처리

아래 표시된 대로 ComputeFrame() 메서드는 실제로 각 프레임의 데이터를 가져오고 크로마 키잉 특수 효과를 실행하는 역할을 합니다.

computeFrame: function() {
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 요소는 아래와 같이 가장 최근의 비디오 프레임 데이터를 표시합니다.

HTML5: Canvas를 사용하여 실시간으로 비디오 처리

라인 2에서 비디오 프레임은 첫 번째 캔버스 ctx1의 그래픽 컨텍스트에 복사되며, 높이와 너비 값을 앞서 저장한 프레임 크기의 절반으로 지정합니다. 그리기 컨텍스트의 drawImage() 메서드에 비디오 요소를 전달하여 현재 비디오 프레임을 그릴 수 있습니다. 결과는 다음과 같습니다.

HTML5: Canvas를 사용하여 실시간으로 비디오 처리

코드의 세 번째 줄은 첫 번째 캔버스 컨텍스트의 getImageData() 메서드를 호출하여 현재 비디오 프레임의 원본 이미지 데이터 복사본을 얻습니다. 이는 우리가 조작할 수 있도록 원시 32비트 픽셀 이미지 데이터를 제공합니다. 코드의 4행에서는 프레임 이미지 데이터의 전체 길이를 4로 나누어 이미지의 총 픽셀 수를 계산합니다.

6번째 코드 줄은 루프의 모든 픽셀을 스캔하고 각 픽셀의 빨간색, 녹색 및 파란색 값을 얻은 다음 이를 미리 정의된 배경색과 비교합니다. foo.png에서 가져온 배경 이미지를 교체합니다.

배경으로 감지된 각 픽셀에 대해 알파 값을 0으로 대체하여 픽셀이 완전히 투명함을 나타냅니다. 결과적으로 최종 이미지의 배경 부분은 100% 투명하므로 라인 13에서 대상의 컨텍스트에 그려지면 콘텐츠가 정적 배경에 겹쳐지는 효과가 있습니다.

결과 이미지는 다음과 같습니다.

HTML5: Canvas를 사용하여 실시간으로 비디오 처리

비디오가 재생될 때 이 작업을 반복하여 프레임별로 처리하여 크로마를 렌더링합니다. -Key 특수 효과.

HTML5: Canvas를 사용하여 실시간으로 비디오를 처리하는 방법에 대한 자세한 내용은 PHP 중국어 웹사이트를 참고하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.