2┃音視訊直播系統之瀏覽器中通過 WebRTC 拍照片加濾鏡並儲存

autofelix發表於2022-05-11

一、拍照原理

  • 好多人小時候應該都學過,在幾張空白的紙上畫同一個物體,並讓物體之間稍有一些變化,然後連續快速地翻動這幾張紙,它就形成了一個小動畫,音視訊播放器就是利用這樣的原理來播放音視訊檔案的

  • 播放器播的是非編碼幀(解碼後的幀),這些非編碼幀就是一幅幅獨立的影像

  • 瀏覽器提供了一個非常強大的物件,稱為Canvas,你可以把它想像成一塊畫布,你可以在上面畫點、面、圖形

  • 拍照原理其實就是獲取攝像頭裡面的非編碼幀資料,並在Canvas上畫出來

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TakePhoto</title>
</head>
<style>
    video {
        width: 800px;
        height: 450px;
    }
</style>

<body>
    <h1>Realtime communication with WebRTC </h1>
    <video autoplay playsinline></video>
    <canvas id="picture"></canvas>
    <button onclick="take_photo()">Take</button>
</body>
<script>
    function take_photo() {
        var picture = document.querySelector('canvas#picture');
        // 設定圖片寬高
        picture.width = 640;
        picture.height = 480;
				
      	// 獲取當前正在播放的視訊,進行繪圖,也就是拍照
        videoplay = document.querySelector('video');
        picture.getContext('2d').drawImage(videoplay, 0, 0, picture.width, picture.height);
    }
</script>

</html>

 

二、Canvas繪圖

  • canvas中提供了 ctx.drawImage(image, dx, dy, dWidth, dHeight) 方法進行繪圖

  • image:可以是一幅圖片,或 HTMLVideoElement,既可以是一幅圖片,也可以是一個 Video 元素

  • dx, dy:圖片起點的 x、y 座標

  • dWidth:圖片的寬度

  • dHeight:圖片的高度

void ctx.drawImage(image, dx, dy, dWidth, dHeight);

 

三、圖片儲存

  • 首先,通過 Canvas 的 toDataURL 方法獲得圖片的 URL 地址

  • 然後,建立一個<a>標籤

  • 將 URL 地址放到<a>標籤中,當使用者點選時就將圖片下載下來

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TakePhoto</title>
</head>
<style>
    video {
        width: 800px;
        height: 450px;
    }
</style>

<body>
    <h1>Realtime communication with WebRTC </h1>
    <video autoplay playsinline></video>
    <canvas id="picture"></canvas>
    <button onclick="take_photo()">Take</button>
    <button onclick="save()"> 儲存 </button>
</body>
<script>
    var canvas = null;
    
    function take_photo() {
        var picture = document.querySelector('canvas#picture');
        // 設定圖片寬高
        picture.width = 640;
        picture.height = 480;

        videoplay = document.querySelector('video');
        canvas = picture.getContext('2d').drawImage(videoplay, 0, 0, picture.width, picture.height);
    }

    function save() {
        var url = canvas.toDataURL("image/jpeg")
        var oA = document.createElement("a");
        oA.download = 'photo';// 設定下載的檔名,預設是'下載'
        oA.href = url;
        document.body.appendChild(oA);
        oA.click();
        oA.remove(); // 下載之後把建立的元素刪除
    }
</script>

</html>

 

四、實現濾鏡

  • 視訊流中獲取到照片後,你還可以通過濾鏡為照片增加點特效,這樣會讓你的照片更加特別

  • 在瀏覽器中對於圖片的濾鏡處理是通過 CSS 來控制的

  • 首先在 HTML 中增加 CSS 的濾鏡程式碼如下:

  • blur:模糊度

  • grayscale:灰度(黑白)

  • invert:反轉

  • sepia:深褐色

  • 當使用者點選拍照時候,我們可以給canvas這個標籤加上一個濾鏡類命即可

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .none {
            -webkit-filter: none;
        }

        .blur {
            -webkit-filter: blur(3px);
        }

        .grayscale {
            -webkit-filter: grayscale(1);
        }

        .invert {
            -webkit-filter: invert(1);
        }

        .sepia {
            -webkit-filter: sepia(1);
        }
    </style>
</head>

<body>
    <h1>Realtime communication with WebRTC </h1>
    <video autoplay playsinline></video>
  	<canvas id="picture"></canvas>
    <button onclick="take_photo()">Take</button>

    <!-- 濾鏡選擇 -->
    <select id="filter">
        <option value="none">None</option>
        <option value="blur">blur</option>
        <option value="grayscale">Grayscale</option>
        <option value="invert">Invert</option>
        <option value="sepia">sepia</option>
    </select>
</body>
<script>
function take_photo() {
    var picture = document.querySelector('canvas#picture');
    // 設定圖片寬高
    picture.width = 640;
    picture.height = 480;
    
    //增加濾鏡
    filtersSelect = document.getElementById('filter')
    picture.className = filtersSelect.value;

    videoplay = document.querySelector('video');
    canvas = picture.getContext('2d').drawImage(videoplay, 0, 0, picture.width, picture.height);
}
</script>

</html>

 

相關文章