通過HTML5的getUserMedia實現拍照功能

PortWatcher發表於2013-12-08

參考HTML5Rocks的這篇文章實現的一個簡單的例子

思路如下:
1. 把冰箱門開啟
2. 把大象放進冰箱裡
3. 把冰箱門關上

好了不開玩笑了,其實思路是:
1. 通過getUserMedia呼叫裝置的攝像頭(電腦、手機都可以,取決於瀏覽器對這個API的支援情況),並將資源放入video標籤。
2. 將video內的視訊資源通過canvas的drawImage API放入canvas裡,這個canvas是不顯示的。
3. 將canvas的內容轉換成base64編碼的webp格式的影像(如果瀏覽器不支援這個格式,會fallback到png格式)放入img裡,於是你就能看到你拍的照片了。

不廢話了,上程式碼:

HTML

<!doctype html>
<html>
<head>
    <title>html5 capture test</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <video autoplay></video>
    <img src="">
    <canvas style="display: none;"></canvas>
    <button id="capture">snapshot</button>


    <script src="index.js"></script>
</body>
</html>

JS

var video = document.querySelector(`video`);
var canvas = document.querySelector(`canvas`);
var ctx = canvas.getContext(`2d`);
var localMediaStream = null;

var snapshot = function () {
    if (localMediaStream) {
        ctx.drawImage(video, 0, 0);
        document.querySelector(`img`).src = canvas.toDataURL(`image/webp`);
    }
};

var sizeCanvas = function () {
    setTimeout(function () {
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        img.width = video.videoWidth;
        img.height = video.videoHeight;
    }, 100);
};

var btnCapture = document.getElementById(`capture`);
btnCapture.addEventListener(`click`, snapshot, false);

navigator.webkitGetUserMedia(
    {video: true},
    function (stream) {
        video.src = window.URL.createObjectURL(stream);
        localMediaStream = stream;
        sizeCanvas();
    },
    function () {
        alert(`your browser does not support getUserMedia`);
    }
);

幾個注意事項:

  • 不同瀏覽器對getUserMedia的支援情況不同,需要加上字首,比如webkitGetUserMedia、mozGetUserMedia、msGetUserMedia,如果你想遮蔽這一問題的話,可以這樣做:
// cross platforms
var myGetUserMedia = navigator.getUserMedia || 
                 navigator.webkitGetUserMedia ||
                 navigator.mozGetUserMedia || 
                 navigator.msGetUserMedia;
  • Chrome對file:///做了很多的限制,跨域就不說了,geolocation也不能在本地下使用,這個getUserMedia也是。
  • 這個sizeCanvas函式做的事情就是保證你拍到的照片的大小和攝像頭拍到的大小是一樣的,否則會出現拍到的照片只有攝像頭錄到的一部分畫面的情況。

相關文章