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



编辑:这部分已经想好了,但另一个问题请参阅下面的第二篇文章

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

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

TLDR

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

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

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

Pyperclip——仅限纯文本。我需要能够从剪贴板上读取二进制数据。

pywin32-一直有丢失DLL文件的错误,所以我确信我做错了什么。需要再尝试一下,但我必须采取的步骤非常复杂(见TLDR部分的最后一句话:)

TKinter——没有读太多,因为它似乎只读纯文本。

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

好吧,我终于开始工作了。以下是感兴趣的人的代码:

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()

世界。。。这对我来说是一个新的记录(发布一个问题,几乎立刻就能找到答案)。

对于那些感兴趣的人,我发现:如何从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',当I应该得到946字节长的东西时,其中的前4个应该是01 00 00 00。(以下是从InsideClipboard保存为.bin文件的剪贴板数据:https://www.dropbox.com/s/bf8yhi1h5z5xvzv/testLevel.bin?dl=1)

最新更新