Pořiďte si selfie pomocí JavaScriptu

V tomto tutoriálu vám ukážeme, jak vytvořit aplikaci JavaScript photobooth, která pořizuje snímky pomocí fotoaparátu na vašem telefonu, notebooku nebo stolním počítači. Předvedeme řadu úžasných nativních rozhraní API, která nám umožnila vytvořit náš projekt bez jakýchkoli externích závislostí, knihoven třetích stran nebo Flash - pouze vanilkový JavaScript!

Aplikace

Pro koncového uživatele je naše aplikace pouze příliš zjednodušenou verzí aplikace pro fotoaparát, kterou najdete na jakémkoli chytrém telefonu. K pořizování snímků využívá hardwarovou kameru – to je vše. Pod pokličkou se však odehrává celá řada JavaScriptových kouzel. Zde je přehled na vysoké úrovni:

  1. Přistupujeme ke vstupu kamery a získáváme z něj video stream pomocí rozhraní getUserMedia API.
  2. Promítněte stream z kamery do prvku videa HTML.
  3. Když chce uživatel pořídit snímek, zkopírujeme aktuální snímek videa a nakreslíme jej na prvek plátna.
  4. Změňte plátno na datovou adresu URL obrázku, kterou lze poté zobrazit na obrazovce nebo stáhnout jako soubor PNG.

V článku níže se podíváme pouze na zajímavější části kódu. Úplný zdroj najdete na stránce Stáhnout tlačítko v horní části této stránky nebo si prohlédněte ukázku na JSfiddle.

Přístup k fotoaparátu

JavaScript poskytuje nativní API pro přístup k libovolnému hardwaru kamery ve formě metody navigator.getUserMedia. Vzhledem k tomu, že zpracovává soukromá data, toto rozhraní API funguje pouze v zabezpečených připojeních HTTPS a před pokračováním vždy požádá o povolení uživatele.

Pokud uživatel povolí aktivovat svou kameru, navigator.getUserMedia nám poskytuje video stream v úspěšném zpětném volání. Tento datový proud se skládá z nezpracovaných dat vysílání přicházejících z kamery a je třeba jej převést na skutečně použitelný zdroj médií s createObjectURL metoda.

navigator.getUserMedia(
    // Options
    {
        video: true
    },
    // Success Callback
    function(stream){

        // Create an object URL for the video stream and
        // set it as src of our HTLM video element.
        video.src = window.URL.createObjectURL(stream);

        // Play the video element to show the stream to the user.
        video.play();

    },
    // Error Callback
    function(err){

        // Most common errors are PermissionDenied and DevicesNotFound.
        console.error(err);

    }
);

Pořízení fotografie

Jakmile spustíme stream videa, můžeme pořizovat snímky ze vstupu kamery. K tomu slouží šikovný trik, který využívá mocný <canvas> prvek k zachycení snímku z běžícího video streamu a jeho uložení do <img> prvek.

function takeSnapshot(){

    var hidden_canvas = document.querySelector('canvas'),
        video = document.querySelector('video.camera_stream'),
        image = document.querySelector('img.photo'),

        // Get the exact size of the video element.
        width = video.videoWidth,
        height = video.videoHeight,

        // Context object for working with the canvas.
        context = hidden_canvas.getContext('2d');

    // Set the canvas to the same dimensions as the video.
    hidden_canvas.width = width;
    hidden_canvas.height = height;

    // Draw a copy of the current frame from the video on the canvas.
    context.drawImage(video, 0, 0, width, height);

    // Get an image dataURL from the canvas.
    var imageDataURL = hidden_canvas.toDataURL('image/png');

    // Set the dataURL as source of an image element, showing the captured photo.
    image.setAttribute('src', imageDataURL); 

}

Samotný prvek canvas ani nemusí být viditelný v DOM. Jeho JavaScript API používáme pouze jako způsob zachycení statického momentu z videa.

Stažení fotografie

Samozřejmě nechceme jen pořizovat nádherné selfie, ale chceme je také ukládat pro budoucí generace. Nejjednodušší způsob, jak to udělat, je pomocí atributu download pro <a> Prvky. V HTML tlačítko vypadá takto:

<a id="dl-btn" href="#" download="glorious_selfie.png">Save Photo</a>

download atribut transformuje naši kotvu z hypertextového odkazu na tlačítko pro stažení. Jeho hodnota představuje výchozí název stahovatelného souboru je aktuální soubor ke stažení uložen v href atribut, který je, jak vidíte, prozatím prázdný. K načtení naší nově pořízené fotografie zde můžeme použít obrázek dataURL z předchozí sekce:

function takeSnapshot(){

    //...

    // Get an image dataURL from the canvas.
    var imageDataURL = hidden_canvas.toDataURL('image/png');

    // Set the href attribute of the download button.
    document.querySelector('#dl-btn').href = imageDataURL;
}

Když nyní někdo klikne na toto tlačítko, bude vyzván ke stažení souboru s názvem glorious_selfie.png , obsahující fotografii, kterou pořídili. Tím je náš malý experiment dokončen!

Závěr

Doufáme, že jste se z tohoto tutoriálu hodně naučili a že se nyní cítíte inspirováni k vytvoření nějakých zázračných fotografických aplikací. Jako vždy můžete klást otázky nebo sdílet nápady v sekci komentářů níže!