是否可以从字节数组而不是文件路径构造 THREE.Texture ?
Is it possible to construct a THREE.Texture from byte array rather than file path?
我有一个服务器客户端系统,其中服务器解析模型文件并使用套接字将顶点数据发送到客户端。当模型包含纹理时,我的问题就出现了。我可以将纹理(png 文件)读取到字节数组并使用套接字将其发送到客户端。但我不知道如何从字节数组创建 THREE.Texture
。
所以这是我的问题,是否可以从字节数组构造一个THREE.Texture
?我怎样才能实现它?
此外,您可以建议其他更好的方法将纹理从服务器发送到客户端。
谢谢。
好的,在网上进行一些研究后,我找到了一种方法。我必须从字节数组创建数据 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' );
}
);
您必须执行以下步骤:
将字节转换为 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
如果您已经有一个来自 websocket 的 byte-array,那么使用 Blobs 有更多的 elegant-solution:
// 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 的 hundreds-of-kilobytes 长字符串时,它不会使开发工具崩溃.
但是还有一种选择(不幸的是还没有得到广泛支持):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;
});
我有一个服务器客户端系统,其中服务器解析模型文件并使用套接字将顶点数据发送到客户端。当模型包含纹理时,我的问题就出现了。我可以将纹理(png 文件)读取到字节数组并使用套接字将其发送到客户端。但我不知道如何从字节数组创建 THREE.Texture
。
所以这是我的问题,是否可以从字节数组构造一个THREE.Texture
?我怎样才能实现它?
此外,您可以建议其他更好的方法将纹理从服务器发送到客户端。
谢谢。
好的,在网上进行一些研究后,我找到了一种方法。我必须从字节数组创建数据 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' );
}
);
您必须执行以下步骤:
将字节转换为 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
如果您已经有一个来自 websocket 的 byte-array,那么使用 Blobs 有更多的 elegant-solution:
// 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 的 hundreds-of-kilobytes 长字符串时,它不会使开发工具崩溃.
但是还有一种选择(不幸的是还没有得到广泛支持):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;
});