I\'ve seen this question and i followed every step, changing the code to satisfy my requirements, that are Python3, Pillow, and ctypes. The less libraries, the better.
The example uses pywin32, which is Python wrapper around Win32 API that hides some low level details you need to take care yourself of if you want to use ctypes
.
Here is how you do it using ctypes
, it adds a functionally of creating globally allocated buffer and copy the data
into that buffer:
#!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()
Whew. Apparently the win32clipboard
library does simplify some things when compared to ctypes
. Your attempt to simply replace one with the other is far from correct.
So I booted up my Windows virtual machine, installed Pillow and rewrote your program, learning from two other answers:
import io
import ctypes
msvcrt = ctypes.cdll.msvcrt
kernel32 = ctypes.windll.kernel32
user32 = ctypes.windll.user32
from PIL import ImageGrab
img = ImageGrab.grab()
output = io.BytesIO()
img.convert('RGB').save(output, 'BMP')
data = output.getvalue()[14:]
output.close()
CF_DIB = 8
GMEM_MOVEABLE = 0x0002
global_mem = kernel32.GlobalAlloc(GMEM_MOVEABLE, len(data))
global_data = kernel32.GlobalLock(global_mem)
msvcrt.memcpy(ctypes.c_char_p(global_data), data, len(data))
kernel32.GlobalUnlock(global_mem)
user32.OpenClipboard(None)
user32.EmptyClipboard()
user32.SetClipboardData(CF_DIB, global_mem)
user32.CloseClipboard()