web-dev-qa-db-ja.com

Three.js:シーンの2DスナップショットをJPGイメージとして作成するにはどうすればよいですか?

次のようなthree.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スナップショットまたはスクリーンショットを作成し、JPGイメージとしてエクスポートすることは可能ですか?

19
confile

フレームを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リンク

 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);
        }
    }
html, body {
    padding:0px;
    margin:0px;
}
canvas {
    width: 100%;
    height: 100%
}
<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>
28
Shiva