如何从Three.js画布中保存图像?

时间:2021-11-07 03:09:57

How do you save an image from a Three.js canvas?

如何从Three.js画布中保存图像?

I'm attempting to use Canvas2Image but it doesn't like to play with Threejs. Since the canvas isn't defined until it has a div to attach the canvas object to.

我正在尝试使用Canvas2Image,但它不喜欢玩Threejs。由于画布没有定义,直到它有一个div来附加画布对象。

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

2 个解决方案

#1


58  

Since the toDataURL is a method of canvas html element, that will work for 3d context too. But you have to take care of couple of things.

由于toDataURL是canvas html元素的一种方法,因此也适用于3d上下文。但是你必须要照顾好几件事。

  1. Make sure when the 3D context is initialized you set preserveDrawingBuffer flag to true, like so:

    确保在初始化3D上下文时将preserveDrawingBuffer标志设置为true,如下所示:

    var context = canvas.getContext("experimental-webgl", {preserveDrawingBuffer: true});
    
  2. Then user canvas.toDataURL() to get the image

    然后用户canvas.toDataURL()来获取图像

In threejs you would have to do the following when the renderer is instantiated:

在threejs中,在实例化渲染器时,您必须执行以下操作:

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

Also, keep in mind this can have performance implications. (Read: https://github.com/mrdoob/three.js/pull/421#issuecomment-1792008)

另外,请记住,这可能会影响性能。 (阅读:https://github.com/mrdoob/three.js/pull/421#issuecomment-1792008)

This is only for webgl renderer, in case of threejs canvasRenderer though, you can simply do renderer.domElement.toDataURL(); directly, no initialization parameter needed.

这仅适用于webgl渲染器,如果是threejs canvasRenderer,则可以简单地执行renderer.domElement.toDataURL();直接,不需要初始化参数。

My webgl experiment: http://jsfiddle.net/TxcTr/3/ press 'p' to screenshot.

我的webgl实验:http://jsfiddle.net/TxcTr/3/按'p'截图。

Props to gaitat, I just followed the link in his comment to get to this answer.

关于步态的道具,我只是按照他评论中的链接来得到这个答案。

#2


22  

I read the conversation posted by Dinesh (https://github.com/mrdoob/three.js/pull/421#issuecomment-1792008) and came up with a solution that won't slow down your application.

我阅读了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;
        }
    } 

With this you can leave the preserveDrawingBuffer-Flag at false and still get the image from THREE.js. Simply set getImageData to true and call render() and you are good to go.

有了这个,您可以将preserveDrawingBuffer-Flag保留为false,并仍然从THREE.js获取图像。只需将getImageData设置为true并调用render()就可以了。

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

Hope this helps people like me who need the high fps :)

希望这能帮助像我这样需要高fps的人:)

#1


58  

Since the toDataURL is a method of canvas html element, that will work for 3d context too. But you have to take care of couple of things.

由于toDataURL是canvas html元素的一种方法,因此也适用于3d上下文。但是你必须要照顾好几件事。

  1. Make sure when the 3D context is initialized you set preserveDrawingBuffer flag to true, like so:

    确保在初始化3D上下文时将preserveDrawingBuffer标志设置为true,如下所示:

    var context = canvas.getContext("experimental-webgl", {preserveDrawingBuffer: true});
    
  2. Then user canvas.toDataURL() to get the image

    然后用户canvas.toDataURL()来获取图像

In threejs you would have to do the following when the renderer is instantiated:

在threejs中,在实例化渲染器时,您必须执行以下操作:

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

Also, keep in mind this can have performance implications. (Read: https://github.com/mrdoob/three.js/pull/421#issuecomment-1792008)

另外,请记住,这可能会影响性能。 (阅读:https://github.com/mrdoob/three.js/pull/421#issuecomment-1792008)

This is only for webgl renderer, in case of threejs canvasRenderer though, you can simply do renderer.domElement.toDataURL(); directly, no initialization parameter needed.

这仅适用于webgl渲染器,如果是threejs canvasRenderer,则可以简单地执行renderer.domElement.toDataURL();直接,不需要初始化参数。

My webgl experiment: http://jsfiddle.net/TxcTr/3/ press 'p' to screenshot.

我的webgl实验:http://jsfiddle.net/TxcTr/3/按'p'截图。

Props to gaitat, I just followed the link in his comment to get to this answer.

关于步态的道具,我只是按照他评论中的链接来得到这个答案。

#2


22  

I read the conversation posted by Dinesh (https://github.com/mrdoob/three.js/pull/421#issuecomment-1792008) and came up with a solution that won't slow down your application.

我阅读了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;
        }
    } 

With this you can leave the preserveDrawingBuffer-Flag at false and still get the image from THREE.js. Simply set getImageData to true and call render() and you are good to go.

有了这个,您可以将preserveDrawingBuffer-Flag保留为false,并仍然从THREE.js获取图像。只需将getImageData设置为true并调用render()就可以了。

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

Hope this helps people like me who need the high fps :)

希望这能帮助像我这样需要高fps的人:)