是否可以从字节数组而不是文件路径构造THREE.Texture?

时间:2017-01-19 09:53:44

标签: javascript three.js client-server

我有一个服务器客户端系统,服务器解析模型文件并使用套接字将顶点数据发送到客户端。当模型包含纹理时,我的问题出现了。我可以将纹理(png文件)读取到字节数组并使用socket将其发送到客户端。但我不知道我将如何从字节数组创建THREE.Texture

所以这是我的问题,是否可以从字节数组构造THREE.Texture?我怎样才能实现它?

此外,您可以建议其他更好的方法将纹理从服务器发送到客户端。

感谢。

3 个答案:

答案 0 :(得分:1)

好的,经过网络上的一些研究后,我找到了一种方法。我必须从字节数组创建数据uri并将其传递给THREE.TextureLoader。这是代码 -

        let data_uri = "data:image/png;base64," + convert_to_base64_string(my_byte_array);

        // instantiate a loader
        let loader_t = new THREE.TextureLoader();
        loader_t.load(
            // resource URL
            data_uri,
            // Function when resource is loaded
            function ( texture ) {


                let plane = scene.getObjectByName("test-texture");
                plane.material.map = texture;

                plane.material.needsUpdate = true;
            },
            // Function called when download progresses
            function ( xhr ) {
                console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
            },
            // Function called when download errors
            function ( xhr ) {
                console.log( 'An error happened' );
            }
        );

答案 1 :(得分:1)

你必须遵循一些步骤:

将字节转换为base64:jou可以使用像https://github.com/beatgammit/base64-js

这样的库

使用base64数据创建图像:

var image = new Image();
image.src =  "data:image/png;base64," + myBase64Datas;

从图像创建纹理。

var texture = new THREE.Texture();
texture.image = image;
image.onload = function() {
    texture.needsUpdate = true;
};

如果您遇到麻烦,可以使用在线base64查看器检查从bytearray到base64的转换,如下所示: http://codebeautify.org/base64-to-image-converter

答案 2 :(得分:1)

如果你已经有一个来自websocket的字节数组,那么使用Blob有一个更优雅的解决方案:

// assuming `byteArray` came in from the websocket
var texture = new THREE.Texture();
var imageBlob = new Blob([byteArray.buffer], {type: "image/png"});
var url = URL.createObjectUrl(imageBlob);

var image = new Image();
image.src = url;
image.onload = function() { 
    texture.image = image; 
    texture.needsUpdate = true; 
};

现在您可以使用正确的URL(类似blob:http://example.com/$uuid),您可以随意使用。这样做的主要好处是可以节省将数据转换为base64所需的时间,并且当它们试图向您显示base64-url的数百KB长字符串时,它不会使devtools崩溃。 / p>

但是还有一个选项(遗憾的是还没有广泛支持):createImageBitmap()。有了这个,我就会这样简单:

var texture = new THREE.Texture();
var imageBlob = new Blob([byteArray.buffer], {type: "image/png"});

createImageBitmap(imageBlob).then(function(imageBitmap) {
    texture.image = imageBitmap;
    texture.needsUpdate = true;
});