2013-03-21 12 views
34

Jak zapisać obraz z płótna Three.js?Jak zapisać obraz z płótna Three.js?

Próbuję użyć Canvas2Image, ale nie lubię grać z Threejs. Ponieważ płótno nie jest zdefiniowane, dopóki nie ma elementu div do dołączenia obiektu canvas.

http://ajaxian.com/archives/canvas2image-save-out-your-canvas-data-to-images

+1

Nie jestem pewien, można. Płótno 2D obsługuje to, ale uważam, że płótno WebGL tego nie robi. –

+0

Zobacz https://github.com/jeromeetienne/threejsboilerplate/blob/master/vendor/threex/THREEx.screenshot.js – gaitat

Odpowiedz

56

Od toDataURL to metoda elementu canvas html, który będzie działał na 3D kontekście zbyt. Ale musisz zająć się kilkoma rzeczami.

  1. Upewnij się, gdy kontekst 3D jest inicjowany ustawić preserveDrawingBuffer flagę prawda, tak jak poniżej:

    var context = canvas.getContext("experimental-webgl", {preserveDrawingBuffer: true}); 
    
  2. Następnie użytkownik canvas.toDataURL() aby uzyskać obraz

W threejs ty będzie musiał wykonać następujące czynności, gdy renderer jest tworzony:

new THREE.WebGLRenderer({ 
    preserveDrawingBuffer: true 
}); 

Należy również pamiętać, że może to mieć wpływ na wydajność. (Czytaj: https://github.com/mrdoob/three.js/pull/421#issuecomment-1792008)

To tylko dla WebGL renderujący, w przypadku threejs canvasRenderer choć można po prostu zrobić renderer.domElement.toDataURL(); bezpośrednio, bez parametru inicjalizacji potrzebne.

Mój internetowy eksperyment: http://jsfiddle.net/TxcTr/3/ naciśnij "p", aby zrzutu ekranu.

Rekwizyty do gaitat, Właśnie podążałem za linkiem w jego komentarzu, aby dostać się do tej odpowiedzi.

+0

Awesome solution. Dzięki! – rjd

+0

Dinesh, czy wiesz, czy to też działa w nodejs, czy nie? – Raha

20

Przeczytałem rozmowę napisaną przez Dinesh (https://github.com/mrdoob/three.js/pull/421#issuecomment-1792008) i znalazłem rozwiązanie, które nie spowolni twojej aplikacji.

function render() { 
     requestAnimationFrame(render); 
     renderer.render(scene, camera); 
     if(getImageData == true){ 
      imgData = renderer.domElement.toDataURL(); 
      getImageData = false; 
     } 
    } 

Dzięki temu można zostawić preserveDrawingBuffer-Flag na false i nadal uzyskać obraz z THREE.js. Po prostu ustaw getImageData na wartość true i wywołaj render() i dobrze jest przejść.

getImageData = true; 
render(); 
console.debug(imgData); 

Nadzieja pomaga to ludzie tacy jak ja, którzy potrzebują wysokiej fps :)

+1

Zasadniczo okazuje się, że przy pomocy trojga potrzebujesz 2 wywołań jeden po drugim: renderer.render (scena, kamera); renderer.domElement.toDataURL(); W wielu przypadkach najprostszym rozwiązaniem może być po prostu umieszczenie ich w oddzielnej funkcji poza normalną pętlą renderowania. – dadasign