在 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 剪贴板中读取二进制数据的主要内容,如果未能解决你的问题,请参考以下文章