在 Blender (python) 中从 Windows 剪贴板中读取二进制数据

Posted

技术标签:

【中文标题】在 Blender (python) 中从 Windows 剪贴板中读取二进制数据【英文标题】:Read binary data off Windows clipboard, in Blender (python) 【发布时间】:2014-12-02 03:18:30 【问题描述】:

编辑:想通了这部分,但有关另一个问题,请参阅下面的第二篇文章。

(这里有一点背景故事,请跳过 TLDR :))

我目前正在尝试为 Blender 编写一些脚本,以帮助改进我玩的游戏的关卡创建工作流程(自然选择 2)。目前,要将几何图形从关卡编辑器移动到 Blender,我必须 1)将编辑器中的文件另存为 .obj 2)将 obj 导入 Blender,然后进行更改。然后我 3) 使用我编写的导出器脚本导出到游戏的关卡格式,以及 4) 在编辑器的新实例中重新打开文件。 5) 从新实例复制关卡数据。 6) 粘贴到主关卡文件中。这是一件很痛苦的事情,而且很明显,除了进行重大编辑之外,甚至完全不鼓励使用该工具。我对改进工作流程的想法:1)在编辑器中将数据复制到剪贴板 2)在 Blender 中运行导入器脚本以加载数据。 3)在搅拌机中运行导出器脚本以保存数据。 4)粘贴回原始文件。这不仅减少了繁琐过程中的两个完整步骤,而且还消除了将额外文件弄乱我的桌面的需要。不过目前,我还没有找到一种将剪贴板数据从 Windows 剪贴板读入 Blender 的方法……至少不需要经过一些非常复杂的安装步骤(例如安装 python 3.1、安装 pywin32、移动 x、y ,z 到blender目录,卸载python 3.1...等...)

TLDR

我需要帮助找到一种在 Blender 中向剪贴板写入/读取 BINARY 数据的方法。我不关心跨平台能力——游戏工具只有 Windows。

理想情况下——虽然显然乞丐不能在这里选择——该解决方案不会使为外行安装脚本变得太困难。我(希望)不是唯一将要使用它的人,所以我希望安装说明尽可能简单。如果python标准库中有可用的解决方案,那就太棒了!

我已经看过/正在看的东西

Pyperclip -- 仅限纯文本。我需要能够从剪贴板上读取 BINARY 数据。

pywin32 -- 不断收到丢失的 DLL 文件错误,所以我确定我做错了什么。需要再试一次,但我必须采取的步骤非常复杂(请参阅 TLDR 部分上方的最后一句话 :))

TKinter -- 没有深入阅读这个,因为它似乎只读取纯文本。

ctypes——实际上是在写这篇文章的过程中发现的。看起来很吓人,但我会试一试。

【问题讨论】:

【参考方案1】:

好吧,我终于搞定了。感兴趣的朋友可以参考一下代码:

from ctypes import *
from binascii import hexlify

kernel32 = windll.kernel32
user32 = windll.user32

user32.OpenClipboard(0)

CF_SPARK = user32.RegisterClipboardFormatW("application/spark editor")

if user32.IsClipboardFormatAvailable(CF_SPARK):
    data = user32.GetClipboardData(CF_SPARK)
    size = kernel32.GlobalSize(data)
    data_locked = kernel32.GlobalLock(data)
    text = string_at(data_locked,size)
    kernel32.GlobalUnlock(data)
else:
    print('No spark data in clipboard!')
user32.CloseClipboard()

【讨论】:

【参考方案2】:

Welp...这对我来说是一个新记录(发布问题并几乎立即找到答案)。

对于那些感兴趣的人,我发现了这个:How do I read text from the (windows) clipboard from python?

这正是我所追求的……有点。我使用该代码作为起点。

而不是CF_TEXT = 1

我用CF_SPARK = user32.RegisterClipboardFormatW("application/spark editor")

这是我从以下获得该函数名称的地方:http://msdn.microsoft.com/en-us/library/windows/desktop/ms649049(v=vs.85).aspx

'W' 存在是因为无​​论出于何种原因,Blender 都看不到普通的“RegisterClipboardFormat”函数,您必须使用“...FormatW”或“...FormatA”。不知道为什么会这样。如果有人知道,我很想听听! :)

无论如何,它还没有真正起作用:仍然需要找到一种方法将这个“数据”对象分解为字节,以便我可以实际使用它,但这应该不会太难。

从头开始,这给我带来了相当大的困难。

这是我的代码

from ctypes import *
from binascii import hexlify

kernel32 = windll.kernel32
user32 = windll.user32

user32.OpenClipboard(0)

CF_SPARK = user32.RegisterClipboardFormatW("application/spark editor")

if user32.IsClipboardFormatAvailable(CF_SPARK):
    data = user32.GetClipboardData(CF_SPARK)
    data_locked = kernel32.GlobalLock(data)
    print(data_locked)
    text = c_char_p(data_locked)
    print(text)
    print(hexlify(text))
    kernel32.GlobalUnlock(data_locked)
else:
    print('No spark data in clipboard!')
user32.CloseClipboard()

没有任何错误,但输出错误。 print(hexlify(text)) 行产生 b'e0cb0c1100000000',当我应该得到 946 字节长的东西时,前 4 个应该是 01 00 00 00。(这是剪贴板数据,从 InsideClipboard 中保存出来作为 .bin 文件:https://www.dropbox.com/s/bf8yhi1h5z5xvzv/testLevel.bin?dl=1)

【讨论】:

以上是关于在 Blender (python) 中从 Windows 剪贴板中读取二进制数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Blender 中从不同的摄像机角度渲染 3d 模型的不同贴图(漫反射、深度、镜面反射、阴影)?

[简单教程]在blender里编写自己的着色器

是否可以从 Blender 中的渲染对象创建 UV 贴图

在 Blender 中运行 python 脚本

Blender-蟒蛇

如何在python pyqt5中从主窗口管理第二个窗口