Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将PIL/枕头图像复制到Windows剪贴板_Python_Winapi_Python Imaging Library_Ctypes_Pillow - Fatal编程技术网

Python 将PIL/枕头图像复制到Windows剪贴板

Python 将PIL/枕头图像复制到Windows剪贴板,python,winapi,python-imaging-library,ctypes,pillow,Python,Winapi,Python Imaging Library,Ctypes,Pillow,我已经看到并遵循了每一步,修改代码以满足我的需求,即Python3、枕头和ctypes。图书馆越少越好 import ctypes from PIL import ImageGrab, Image from io import BytesIO user32 = ctypes.windll.user32 img = ImageGrab.grab() output = BytesIO() img.convert("RGB").save(output, "BMP") data = output.g

我已经看到并遵循了每一步,修改代码以满足我的需求,即Python3、枕头和ctypes。图书馆越少越好

import ctypes
from PIL import ImageGrab, Image
from io import BytesIO

user32 = ctypes.windll.user32

img = ImageGrab.grab()
output = BytesIO()
img.convert("RGB").save(output, "BMP")
data = output.getvalue()[14:]
output.close()

user32.OpenClipboard()
user32.EmptyClipboard()
user32.SetClipboardData(user32.CF_DIB, data)
user32.CloseClipboard()
这是从我的脚本中剥离出来的代码,我认为,这与问题中移植到我的需求中的代码是相同的。执行时,它应将当前桌面复制到剪贴板。我得到的是:

File "C:\Users\Gcq\Documents\python\Screen\Screen.py", line 132, in shot
    user32.OpenClipboard()
ValueError: Procedure probably called with not enough arguments (4 bytes missing)

很抱歉,我在这里问了这么一个(可能)简单的问题,但我真的不知道是什么失败了,而且ctypes不是我的事。

呼。显然,与
ctypes
相比,
win32clipboard
库确实简化了一些事情。你试图简单地用另一个来代替一个是远远不正确的

因此,我启动了我的Windows虚拟机,安装了Pillow并重写了您的程序,从以下两个方面学习:

该示例使用的是一个围绕Win32 API的Python包装器,它隐藏了一些低级细节,如果您想使用
ctypes
,则需要自行处理这些细节

下面是如何使用
ctypes
执行此操作的,它添加了一个创建全局分配缓冲区的功能,并将
数据
复制到该缓冲区中:

#!python

from PIL import Image
#from cStringIO import StringIO
from io import BytesIO
from ctypes import *
from ctypes.wintypes import *

HGLOBAL = HANDLE
SIZE_T = c_size_t
GHND = 0x0042
GMEM_SHARE = 0x2000

GlobalAlloc = windll.kernel32.GlobalAlloc
GlobalAlloc.restype = HGLOBAL
GlobalAlloc.argtypes = [UINT, SIZE_T]

GlobalLock = windll.kernel32.GlobalLock
GlobalLock.restype = LPVOID
GlobalLock.argtypes = [HGLOBAL]

GlobalUnlock = windll.kernel32.GlobalUnlock
GlobalUnlock.restype = BOOL
GlobalUnlock.argtypes = [HGLOBAL]

CF_DIB = 8

OpenClipboard = windll.user32.OpenClipboard
OpenClipboard.restype = BOOL 
OpenClipboard.argtypes = [HWND]

EmptyClipboard = windll.user32.EmptyClipboard
EmptyClipboard.restype = BOOL
EmptyClipboard.argtypes = None

SetClipboardData = windll.user32.SetClipboardData
SetClipboardData.restype = HANDLE
SetClipboardData.argtypes = [UINT, HANDLE]

CloseClipboard = windll.user32.CloseClipboard
CloseClipboard.restype = BOOL
CloseClipboard.argtypes = None

#################################################

image = Image.new("RGB", (200, 200), (255, 0, 0))

#output = StringIO()
output = BytesIO()
image.convert("RGB").save(output, "BMP")
data = output.getvalue()[14:]
output.close()

hData = GlobalAlloc(GHND | GMEM_SHARE, len(data))
pData = GlobalLock(hData)
memmove(pData, data, len(data))
GlobalUnlock(hData)

OpenClipboard(None)
EmptyClipboard()
SetClipboardData(CF_DIB, pData)
CloseClipboard()

+1.更一般地说,只是盲目地从Win32 DLL中调用函数从来都不是一个好主意。至少它不会像在POSIX上那样经常崩溃……但是你确实需要在MSDN上查看函数,发送正确的参数,并经常设置
argtypes
和/或
restype
,然后才能使用它。是的,我现在觉得很愚蠢。它起作用了!现在我有另一个问题:我不能粘贴图像。至少Word不接受它。@gcq仍在努力解决它。显然这比你想象的要困难得多。
global_data
是指针,句柄
global_mem
(指向内部数据结构;它不是句柄表的小索引)。您需要为这些文件声明
restype
,否则您的代码在Win64上不正确。ctypes默认将数字转换为C
int
。另外,如果您不使用
c\u void\u p
手动换行,您还需要设置
argtypes
。嗯,我肯定不是这方面的专家@gcq,您可能应该使用另一个答案(Python3现在已经修复了)。
#!python

from PIL import Image
#from cStringIO import StringIO
from io import BytesIO
from ctypes import *
from ctypes.wintypes import *

HGLOBAL = HANDLE
SIZE_T = c_size_t
GHND = 0x0042
GMEM_SHARE = 0x2000

GlobalAlloc = windll.kernel32.GlobalAlloc
GlobalAlloc.restype = HGLOBAL
GlobalAlloc.argtypes = [UINT, SIZE_T]

GlobalLock = windll.kernel32.GlobalLock
GlobalLock.restype = LPVOID
GlobalLock.argtypes = [HGLOBAL]

GlobalUnlock = windll.kernel32.GlobalUnlock
GlobalUnlock.restype = BOOL
GlobalUnlock.argtypes = [HGLOBAL]

CF_DIB = 8

OpenClipboard = windll.user32.OpenClipboard
OpenClipboard.restype = BOOL 
OpenClipboard.argtypes = [HWND]

EmptyClipboard = windll.user32.EmptyClipboard
EmptyClipboard.restype = BOOL
EmptyClipboard.argtypes = None

SetClipboardData = windll.user32.SetClipboardData
SetClipboardData.restype = HANDLE
SetClipboardData.argtypes = [UINT, HANDLE]

CloseClipboard = windll.user32.CloseClipboard
CloseClipboard.restype = BOOL
CloseClipboard.argtypes = None

#################################################

image = Image.new("RGB", (200, 200), (255, 0, 0))

#output = StringIO()
output = BytesIO()
image.convert("RGB").save(output, "BMP")
data = output.getvalue()[14:]
output.close()

hData = GlobalAlloc(GHND | GMEM_SHARE, len(data))
pData = GlobalLock(hData)
memmove(pData, data, len(data))
GlobalUnlock(hData)

OpenClipboard(None)
EmptyClipboard()
SetClipboardData(CF_DIB, pData)
CloseClipboard()