2013-03-21 6 views
34

Wie speichern Sie ein Bild von einer Three.js-Zeichenfläche?Wie speichern Sie ein Bild von einer Three.js-Arbeitsfläche?

Ich versuche Canvas2Image zu verwenden, aber es mag nicht mit Threejs zu spielen. Da die Arbeitsfläche erst dann definiert wird, wenn sie über ein Div verfügt, mit dem das Arbeitsflächenobjekt verknüpft werden kann.

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

+1

Ich bin nicht sicher, Sie können. 2D-Canvas unterstützt dies, aber ich glaube, dass ein WebGL-Canvas dies nicht tut. –

+0

Werfen Sie einen Blick auf https://github.com/jeromeetienne/threejsboilerplate/blob/master/vendor/threex/THREEx.screenshot.js – gaitat

Antwort

56

Da die toDataURL ist eine Methode der Leinwand html-Element, das auch für 3D-Kontext funktionieren wird. Aber du musst auf ein paar Dinge aufpassen.

  1. Stellen Sie sicher, wenn die 3D-Kontext Sie preserveDrawingBuffer Flag auf true gesetzt initialisiert wird, etwa so:

    var context = canvas.getContext("experimental-webgl", {preserveDrawingBuffer: true}); 
    
  2. Dann Benutzer canvas.toDataURL() das Bild

In threejs erhalten Sie müsste Folgendes ausführen, wenn der Renderer instanziiert wird:

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

Denken Sie auch daran, dass dies Auswirkungen auf die Leistung haben kann. (Lesen Sie: https://github.com/mrdoob/three.js/pull/421#issuecomment-1792008)

Dies ist nur für webgl Renderer, bei threejs canvasRenderer aber Sie einfach renderer.domElement.toDataURL(); tun kann direkt, keine Initialisierung Parameter benötigt.

Mein Webgl-Experiment: http://jsfiddle.net/TxcTr/3/ drücken Sie 'p' zum Screenshot.

Requisiten zu gaitat, ich folgte nur dem Link in seinem Kommentar, um zu dieser Antwort zu gelangen.

+0

Tolle Lösung. Vielen Dank! – rjd

+0

Dinesh, weißt du, ob das auch in nodejs funktioniert oder nicht? – Raha

20

Ich las die Konversation von Dinesh (https://github.com/mrdoob/three.js/pull/421#issuecomment-1792008) und kam mit einer Lösung, die Ihre Anwendung nicht verlangsamen wird.

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

diese gemeinsam mit Ihnen den preserveDrawingBuffer-Flag auf falsch verlassen können und immer noch das Bild von Three.js bekommen. Setzen Sie einfach getImageData auf true und rufen Sie render() auf und Sie können loslegen.

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

hoffe, das hilft Menschen wie mich, die hohe fps brauchen :)

+1

Grundsätzlich stellt sich heraus, dass man bei 3js 2 Aufrufe nacheinander benötigt: renderer.render (Szene, Kamera); renderer.domElement.toDataURL(); In vielen Fällen kann der einfachste Ansatz darin bestehen, sie in eine separate Funktion außerhalb der normalen Rendering-Schleife einzufügen. – dadasign

Verwandte Themen