2013-03-21 2 views
34

Как сохранить изображение из холста Three.js?Как сохранить изображение из холста Three.js?

Я пытаюсь использовать Canvas2Image, но он не любит играть с Threejs. Поскольку холст не определен, пока он не имеет div для прикрепления объекта canvas.

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

+1

Я не уверен, что вы можете. 2D-холст поддерживает это, но я полагаю, что холст WebGL этого не делает. –

+0

Взгляните на https://github.com/jeromeetienne/threejsboilerplate/blob/master/vendor/threex/THREEx.screenshot.js – gaitat

ответ

56

Поскольку toDataURL является способом холста элемента HTML, который будет работать для 3d контекста тоже. Но вам нужно позаботиться о двух вещах.

  1. Убедитесь, когда 3D контекст инициализируется вы установите preserveDrawingBuffer флаг так, как так:

    var context = canvas.getContext("experimental-webgl", {preserveDrawingBuffer: true}); 
    
  2. Затем пользователь canvas.toDataURL() получить изображение

В threejs вы должен был бы выполняться после создания экземпляра визуализации:

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

Также имейте в виду, что это может иметь последствия для производительности. (Прочитано: https://github.com/mrdoob/three.js/pull/421#issuecomment-1792008)

Это только для WebGL визуализатора, в случае threejs canvasRenderer, хотя, вы можете просто сделать renderer.domElement.toDataURL(); непосредственно, ни один из параметров инициализации не требуется.

Мой эксперимент webgl: http://jsfiddle.net/TxcTr/3/ press 'p' на скриншот.

Подходит к gaitat, я только что перешел по ссылке в его комментарии, чтобы получить ответ.

+0

Удивительное решение. Благодаря! – rjd

+0

Dinesh, знаете ли вы, что это тоже будет работать в nodejs или нет? – Raha

20

Я прочитал разговор, отправленный Dinesh (https://github.com/mrdoob/three.js/pull/421#issuecomment-1792008), и придумал решение, которое не замедлит ваше приложение.

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

При этом вы можете оставить preserveDrawingBuffer-Flag в ложь и до сих пор получить изображение от three.js. Просто установите getImageData в true и вызовите render(), и вам хорошо идти.

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

Надеется, что это помогает людям, как я, которые нуждаются в высоком фпс :)

+1

В основном получается, что с тремя js вам нужно 2 вызова один за другим: renderer.render (сцена, камера); renderer.domElement.toDataURL(); Во многих случаях простейший подход может заключаться в том, чтобы поместить их в некоторую отдельную функцию вне обычного цикла рендеринга. – dadasign

Смежные вопросы