将从Python发送的字节数组字符串转换为ArrayBuffer。

huangapple go评论90阅读模式
英文:

Convert Binary File Data To ArrayBuffer Sent From Python As Byte-Array String

问题

I can help you translate the provided text into Chinese. Here's the translation:

我正在开发一个使用PyQt5和PyQtWebEngine创建浏览器窗口的Python应用程序。使用QWebChannel,我能够在Web应用程序和Python程序之间来回发送字符串。我希望利用这个功能来加载外部文件,比如GLB模型。

我需要在Python中读取文件,然后将字节数据作为字符串发送到Web应用程序,在那里我会将其转换为ArrayBuffer以便使用。我大致遵循此处的讨论,除了文件是使用JavaScript中的FileReader读取而不是使用Python读取之外,其他都一样。

在我的Python代码中,我正在这样读取文件:

@pyqtSlot(result=str)
def load_binary_data(self):
    file = open("model.glb", "rb")
    byte_array = str(file.read())
    return byte_array

使用QWebChannel,我可以在我的JavaScript代码中访问上述Python函数。为了将字符串转换为ArrayBuffer,我正在使用TextEncoder:

bridge.load_binary_data((byteArrayString)=>{
    var byteArray = new TextEncoder().encode(byteArrayString)
    var arrayBuffer = byteArray.buffer;
})

使用ThreeJS,我应该能够使用loader.parse()加载ArrayBuffer格式的模型,就像这样:

const loader = new GLTFLoader()
loader.parse( arrayBuffer, '', ( gltf ) => {
    // 做一些操作
})

然而,当我尝试加载模型时,我收到以下错误消息:

在JSON位置0处意外的'b'标记

我猜想从Python发送字节数组字符串到我的Web应用程序时存在问题,因为整个字符串周围有b''包装,似乎GLTFLoader().parse()不太喜欢这样的格式。我无法弄清楚如何解决这个问题,正确的方法是什么?

我应该如何正确地将从Python发送的字节数组字符串转换为JavaScript中的ArrayBuffer?

(Note: The translation is based on the provided text. If you have specific technical terms or code-related phrases that need further translation, please let me know.)

英文:

I'm developing a Python App which uses PyQt5 and PyQtWebEngine to create a browser window. Using QWebChannel I'm able to send strings back and forth between the Web Application and the Python program. I want to use this feature to load in external files such as GLB Models.

I need to read the file in Python then send the byte data as a string to the Web Application where I convert it into an ArrayBuffer before its usable. I'm loosely following the dissussion here which does the exact same thing except that the file is read using FileReader in JavaScript instead of reading it with Python.

In my Python Code I'm doing this to read the file:

@pyqtSlot(result=str)
def load_binary_data(self):
    file = open("model.glb", "rb")
    byte_array = str(file.read())
    return byte_array

With QWebChannel I can access the above Python function inside my Javascript code. To convert the string to an ArrayBuffer I'm using TextEncoder:

bridge.load_binary_data((byteArrayString)=>{
    var byteArray = new TextEncoder().encode(byteArrayString)
    var arrayBuffer = byteArray.buffer;
})

With ThreeJS I'm supposed to be able to load a model as ArrayBuffer using loader.parse() like this:

const loader = new GLTFLoader()
loader.parse( arrayBuffer, '', ( gltf ) => {
    // do stuff
})

However when I try to load the Model I get this error:

Unexpected token b in JSON at position 0

I'm gussing there is something wrong with how I send the byte array as a string from Python to my Web Application as there is this b'' wrapping around the entire string which GLTFLoader().parse() does not seem to like very much. I'm cannot figure out how to solve this issue, what would be the correct approach here?

How do I correctly convert the byte-array string sent from Python to an ArrayBuffer in my JavScript?

答案1

得分: 0

感谢 @Obaskly,我得以解决!

这是Python代码:

@pyqtSlot(result=str)
def load_binary_data(self):
    file = open("model.glb", "rb")
    byte_array = file.read()
    bytes_base64 = (base64.b64encode(byte_array)).decode()
    return bytes_base64

这是JavaScript代码:

bridge.load_binary_data((base64_string) => {
    var binaryString = atob(base64_string);
    var bytes = new Uint8Array(binaryString.length);
    for (var i = 0; i < binaryString.length; i++) {
        bytes[i] = binaryString.charCodeAt(i);
    }
    var arrayBuffer = bytes.buffer;

    const loader = new GLTFLoader()
    loader.parse(arrayBuffer, '', (gltf) => {
        // 进行操作
    })
})

这个代码非常顺利,模型可以成功加载。

英文:

Thanks to @Obaskly I could figure it out!

This is the Python Code:

@pyqtSlot(result=str)
def load_binary_data(self):
    file = open(&quot;model.glb&quot;, &quot;rb&quot;)
    byte_array = file.read()
    bytes_base64 = (base64.b64encode(byte_array)).decode()
    return bytes_base64

And This the JavaScript Code:

bridge.load_binary_data((base64_string)=&gt;{

    var binaryString = atob(base64_string);
    var bytes = new Uint8Array(binaryString.length);
    for (var i = 0; i &lt; binaryString.length; i++) {
        bytes[i] = binaryString.charCodeAt(i);
    }
    var arrayBuffer = bytes.buffer;

    const loader = new GLTFLoader()
    loader.parse( arrayBuffer, &#39;&#39;, ( gltf ) =&gt; {
        // Do Stuff
    })
})

This works like a charm, the model is loaded without an issue.

huangapple
  • 本文由 发表于 2023年6月8日 06:34:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76427496.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定