【问题标题】:Is it possible to construct a THREE.Texture from byte array rather than file path?是否可以从字节数组而不是文件路径构造 THREE.Texture ?
【发布时间】:2017-01-19 09:53:44
【问题描述】:

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

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

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

谢谢。

【问题讨论】:

    标签: javascript three.js client-server


    【解决方案1】:

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

    // 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 所需的时间,并且当 devtools 尝试向您显示 base64-url 的数百 KB 长字符串时,它不会崩溃。

    但还有另外一种选择(遗憾的是还没有得到广泛支持):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;
    });
    

    【讨论】:

    • 嗨,我尝试使用 URL.createObjectUrl 函数,但出现“URL.createObjectUrl 不是函数”错误。你有什么想法吗?
    • @badcode 这真的很奇怪。根据developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL 的说法,这已经被浏览器广泛支持了好几年了。你在什么平台上使用这个?
    • @Martin Schuhfuß 我遇到了问题:)。它是 createObjectURL(),而不是 createObjectUrl()
    • 啊,这些东西太难发现了!我不想知道我在这些问题上浪费了多少时间 :D 很高兴你找到了!
    【解决方案2】:

    好的,经过对网络的一些研究,我找到了一种方法。我必须从字节数组创建数据 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' );
                }
            );
    

    【讨论】:

      【解决方案3】:

      你必须遵循一些步骤:

      将字节转换为base64:你可以使用像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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-15
        • 2021-05-03
        • 1970-01-01
        • 1970-01-01
        • 2017-10-11
        • 2015-08-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多