2013-08-28 8 views
5

Ostatnio próbowałem stworzyć fotobudkę, opierając się na Webrtc i prawie ukończyłem cały kod, z wyjątkiem tego, że nie byłem w stanie wymyślić sposobu na zapisanie obrazu po został schwytany.Jak zapisać obraz z płótna

Jest to najbliżej Doszedłem tak daleko, by osiągnąć swój cel:

<meta charset="UTF-8" /> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> 
    <title>fotogoof</title> 
    <link rel="Stylesheet" href="css/bootstrap.css"/> 
    <link rel="Stylesheet" href="css/style.css"/> 
    <script type="text/javascript"> 
      window.onload = function() { 
       var img = document.getElementById('screenshot'); 
       var button = document.getElementById('saveImage'); 
       img.src = ''; 
       img.onload = function() { 
        button.removeAttribute('disabled'); 
       }; 
       button.onclick = function() { 
        window.location.href = img.src.replace('image/png', 'image/octet-stream'); 
       }; 
      }; 
    </script> 
    </head> 
    <div class="navbar navbar-inverse navbar-fixed-top"> 
    <div class="navbar-inner"> 
     <div class="container"> 
     <h2 class="brand">Html5 Photobooth</h1> 
     </div> 
    </div> 
    </div> 
    <div class="container" id="body-wrap"> 
    <div class="container" id="main"> 
     <div class="span10"> 
     <div id="video-container"> 
     <canvas width="400" height="320" class="mask"></canvas> 
      <div id="counter"> 
      </div> 
     </div> 
     <br><div id="pic-holder" class="pull-left"><img id="screenshot"></div></br> 
     <input id="saveImage" type="button" value="save image" disabled="disabled"/> 
     </div> 
    </div> 
    </div> 
    </div> 

Kod jest zasadniczo biorąc strumienia kamery i karmienie go do elementu canvas. Naciśnięcie spacji uruchamia zrzut ekranu, który pojawia się jako obraz. Ponieważ nie mogę podać dokładnego źródła pobieranego pliku, przycisk otwiera tylko obraz w innej karcie w przeglądarce, a nie działa poprawnie. Byłbym wdzięczny za pewne informacje, jak mogę to rozwiązać. Z góry dziękuję.

Ja już udało się zrobić przechwycić strumień z płótna na obrazie z tego kawałka kodu:

document.addEventListener ('keydown', function (event) { 
     if(event.keyCode == 32) { 
     document.querySelector('#screenshot').src = canvas.toDataURL('image/webp') 
     } 
}) 

Co chcę wiedzieć, w jaki sposób, aby umożliwić użytkownikowi zapisać obraz na ich komputer stamtąd.

+0

Musisz dodać identyfikator do elementu canvas, aby moja odpowiedź zadziałała. –

+0

Możliwy duplikat [jak zapisać płótno jako obraz png?] (Http://stackoverflow.com/questions/11112321/how-to-save-canvas-as-png-image) –

Odpowiedz

-1

W odniesieniu do pierwszego zadania można wyeksportować zawartość obszaru roboczego do obrazu za pomocą metody toDataUrl obsługiwanej przez obiekt canvas.

var canvas = document.getElementById("canvas"); 
if (canvas.getContext) { 
    var ctx = canvas.getContext("2d");    // Get the context for the canvas. 
    var myImage = canvas.toDataURL("image/png");  // Get the data as an image. 
} 

var image = document.getElementById("screenshot"); // Get the image object. 
image.src = myImage; 
16

Jeśli dobrze rozumiem, chcesz pobrać (tj. Podać okno dialogowe zapisu dla użytkownika, aby wybrać lokalizację) obraz do komputera użytkownika?

Jeśli więc można użyć tego fragmentu:

function download(canvas, filename) { 

    /// create an "off-screen" anchor tag 
    var lnk = document.createElement('a'), 
     e; 

    /// the key here is to set the download attribute of the a tag 
    lnk.download = filename; 

    /// convert canvas content to data-uri for link. When download 
    /// attribute is set the content pointed to by link will be 
    /// pushed as "download" in HTML5 capable browsers 
    lnk.href = c.toDataURL(); 

    /// create a "fake" click-event to trigger the download 
    if (document.createEvent) { 

     e = document.createEvent("MouseEvents"); 
     e.initMouseEvent("click", true, true, window, 
         0, 0, 0, 0, 0, false, false, false, 
         false, 0, null); 

     lnk.dispatchEvent(e); 

    } else if (lnk.fireEvent) { 

     lnk.fireEvent("onclick"); 
    } 
} 

Teraz wszystko, co musisz zrobić, to zapewnić domyślną nazwę pliku i wywołać funkcję:

download(myCanvas, 'untitled.png'); 

Jeśli zamiast tego średni zapisać bezpośrednio na dysku twardym użytkownika, to nie może ze względów bezpieczeństwa.

Zawsze jest opcja korzystania z lokalnej pamięci masowej, takiej jak File API lub indeksowana DB - ale ponieważ są one ukryte w teście, a użytkownik będzie miał dostęp tylko do "plików" przez przeglądarkę, więc być może nie tak wygodne.

+0

+1 Dobra odpowiedź. Biorąc pod uwagę, że płótno jest doskonałym medium do prezentowania danych i rozrywki, wygląda na to, że twórcy przeglądarek naprawdę powinni zapewnić bardziej bezpośrednią metodę zapisywania obrazu na dysku lokalnym - może coś, co spełnia wymogi bezpieczeństwa, wymagając od użytkownika kliknięcia przycisku OK okno dialogowe z ostrzeżeniem. – markE

+0

Dzięki @markE. Zgadzam się, funkcja taka jak "zezwól tej witrynie na zapisanie w [tej] lokalizacji" byłaby świetna. – K3N

+0

Przepraszam, jestem nieco zdezorientowany. Czy "download (myCanvas," untitled.png ");" część kodu przechodzi bezpośrednio po części "funkcja pobierania (płótno, nazwa pliku)"? – user2724072

0

Mam teraz zawarte w moim kodzie html:

<div id="download"> 
    <p><label for="imageName">Image name:</label> <input type="text" placeholder="My Photobooth Pic" id="imageName"></p> 
    <p>If you want, you can <button>Download</button> the image.</p> 
</div> 

a ja updated mój kod JavaScript, żeby to teraz to:

var _filenameInput = document.getElementById('imageName'), 
var _downloadButton = document.querySelector('#download button'), 

document.addEventListener ('keydown', function (event) { 
      if(event.keyCode == 32) { 
      document.querySelector('#screenshot').src = canvas.toDataURL('image/webp') 
     } 

}) 

_downloadButton.addEventListener('click', _downloadImage); 

var _downloadImage = function(e) { 

    /** do download **/ 
    var imageDataUrl = canvas.toDataURL('image/png').substring(22); 
    var byteArray = Base64Binary.decode(imageDataUrl); 
    var blob = new Blob([byteArray], {type:'image/png'}); 
    var url = window.URL.createObjectURL(blob); 

    var link = document.createElement('a'); 
    link.setAttribute('href', url); 
    var filename = _filenameInput.value; 
    if (!filename) { 
     filename = _filenameInput.getAttribute('placeholder'); 
    } 
    link.setAttribute('download', filename + '.png'); 
    link.addEventListener('click', function() { 
     _downloadButton.className = 'downloaded'; 
    }); 

    var event = document.createEvent('MouseEvents'); 
    event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null); 
    link.dispatchEvent(event); 
}; 
})(); 
}; 

To wciąż nie jest dobre chociaż. Co wy myślicie? Naprawdę doceniam pomoc.

0

miałem ten problem i jest to najlepsze rozwiązanie bez jakichkolwiek zewnętrznych lub dodatkowych bibliotek Scenariusz: w tagach JavaScript lub pliku utworzyć tę funkcję: Zakładamy tutaj, że płótno to płótno:

function download(){ 
     var download = document.getElementById("download"); 
     var image = document.getElementById("canvas").toDataURL("image/png") 
        .replace("image/png", "image/octet-stream"); 
     download.setAttribute("href", image); 

    } 

W część ciała twojego HTML określa przycisk:

<a id="download" download="image.png"><button type="button" onClick="download()">Download</button></a> 

To działa, a łącze pobierania wygląda jak przycisk.