Three.js:如何将场景的2D SnapShot设为JPG图像?

时间:2014-10-04 14:18:41

标签: javascript html html5 three.js webgl

我有一个像以下一样的3.js场景:

            var scene = new THREE.Scene();
            var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);

            var renderer = new THREE.WebGLRenderer();
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(renderer.domElement);

            var geometry = new THREE.BoxGeometry(1,1,1);
            var material = new THREE.MeshBasicMaterial({color: 0x00ff00});
            var cube = new THREE.Mesh(geometry, material);
            scene.add(cube);

            camera.position.z = 5;

            var render = function () {
                requestAnimationFrame(render);

                cube.rotation.x += 0.1;
                cube.rotation.y += 0.1;

                renderer.render(scene, camera);
            };

            render();

是否可以从场景制作2D SnapShot或ScreenShot并将其导出为JPG图像?

1 个答案:

答案 0 :(得分:27)

您需要做的一些事情是将帧保存为jpg图像。

首先像这样初始化webgl上下文

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

preserveDrawingBuffer标志将帮助您获取当前帧的base64编码 代码将是这样的

var strMime = "image/jpeg";
imgData = renderer.domElement.toDataURL(strMime);

现在,您可能希望使用.jpg扩展名保存文件,但并非所有浏览器都允许您指定文件名。 我找到的最佳解决方案是this SO thread

因此我们的脚本将检查浏览器是否允许它创建一个新的anchor元素并设置其download并单击它(这将以指定的文件名保存文件)否则它将只下载文件,但用户必须使用.jpg扩展名重命名才能打开它。

Codepen Link



 var camera, scene, renderer;
    var mesh;
    var strDownloadMime = "image/octet-stream";

    init();
    animate();

    function init() {

        var saveLink = document.createElement('div');
        saveLink.style.position = 'absolute';
        saveLink.style.top = '10px';
        saveLink.style.width = '100%';
        saveLink.style.background = '#FFFFFF';
        saveLink.style.textAlign = 'center';
        saveLink.innerHTML =
            '<a href="#" id="saveLink">Save Frame</a>';
        document.body.appendChild(saveLink);
        document.getElementById("saveLink").addEventListener('click', saveAsImage);
        renderer = new THREE.WebGLRenderer({
            preserveDrawingBuffer: true
        });
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        //

        camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
        camera.position.z = 400;

        scene = new THREE.Scene();

        var geometry = new THREE.BoxGeometry(200, 200, 200);



        var material = new THREE.MeshBasicMaterial({
            color: 0x00ff00
        });

        mesh = new THREE.Mesh(geometry, material);
        scene.add(mesh);

        //

        window.addEventListener('resize', onWindowResize, false);

    }

    function onWindowResize() {

        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();

        renderer.setSize(window.innerWidth, window.innerHeight);

    }

    function animate() {

        requestAnimationFrame(animate);

        mesh.rotation.x += 0.005;
        mesh.rotation.y += 0.01;

        renderer.render(scene, camera);

    }

    function saveAsImage() {
        var imgData, imgNode;

        try {
            var strMime = "image/jpeg";
            imgData = renderer.domElement.toDataURL(strMime);

            saveFile(imgData.replace(strMime, strDownloadMime), "test.jpg");

        } catch (e) {
            console.log(e);
            return;
        }

    }

    var saveFile = function (strData, filename) {
        var link = document.createElement('a');
        if (typeof link.download === 'string') {
            document.body.appendChild(link); //Firefox requires the link to be in the body
            link.download = filename;
            link.href = strData;
            link.click();
            document.body.removeChild(link); //remove the link when done
        } else {
            location.replace(uri);
        }
    }
&#13;
html, body {
    padding:0px;
    margin:0px;
}
canvas {
    width: 100%;
    height: 100%
}
&#13;
<script src="http://cdnjs.cloudflare.com/ajax/libs/three.js/r69/three.min.js"></script>
<script src="http://threejs.org/examples/js/libs/stats.min.js"></script>
&#13;
&#13;
&#13;