使用PIL和win32clipboard在Python中将图像写入Windows剪贴板?

5

我正在尝试打开一个图像文件并将该图像复制到Windows剪贴板。是否有方法可以解决这个问题:

import win32clipboard
from PIL import Image

def send_to_clipboard(clip_type, data): 
    win32clipboard.OpenClipboard()
    win32clipboard.EmptyClipboard()
    win32clipboard.SetClipboardData(clip_type, data) 
    win32clipboard.CloseClipboard()

clip_type = win32clipboard.CF_BITMAP
filepath = 'c:\\temp\\image.jpg'

im = Image.open(filepath) 
data = im.tobitmap() # fails with valueerror: not a bitmap
# data = im.tostring() runs, but receiving programs can't read the results
send_to_clipboard(clip_type, data)

我可以安装PythonMagick等库,但不想为一次性程序安装另一个库。
4个回答

9
from cStringIO import StringIO
import win32clipboard
from PIL import Image

def send_to_clipboard(clip_type, data):
    win32clipboard.OpenClipboard()
    win32clipboard.EmptyClipboard()
    win32clipboard.SetClipboardData(clip_type, data)
    win32clipboard.CloseClipboard()

filepath = 'image.jpg'
image = Image.open(filepath)

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

send_to_clipboard(win32clipboard.CF_DIB, data)

为什么是神奇的数字14?它在Python 3或64位Python上会出问题吗?非常感谢您提供如此有用的答案。 - Michael Platings
@MichaelPlatings 的14指的是BMP文件具有14字节的头。该头信息无论BMP文件被复制到32位或64位系统中,都会保留14个字节的长度。在Python 3中,你需要将 StringIO 改为 BytesIO - Damian Yerrick
3
针对Python 3,需要将两行代码修改如下:from io import BytesIO ... output = BytesIO() - Rahul Dolas
@DamianYerrick PNG 的值是多少? - Delrius Euphoria
1
@CoolCloud 请查看yfyang的回答。PNG的头部是8个字节,但Windows剪贴板不使用PNG。 - Damian Yerrick

1
补充其他答案,也可以将PNG(和可能的其他格式)复制到剪贴板。我使用了以下代码:
buffer = io.BytesIO()
img_out.save(fp=buffer, format='PNG')

clipboard_format = win32clipboard.RegisterClipboardFormat('PNG')
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardData(clipboard_format, buffer.getvalue())
win32clipboard.CloseClipboard()

buffer.close()

这个答案详细介绍了一些程序对非标准剪贴板格式“PNG”的支持,而我在我的回答中使用了它。如果您想要复制到的程序接受自定义剪贴板格式,那么这是一个替代方案。当然,您也可以定义许多标准和/或非标准剪贴板格式。


1
BMP 的文件头偏移量为 14 字节。BMP 也被称为设备无关位图(DIB)文件格式,因此您不需要担心魔数 14。
顺便提一下,它确实需要 Windows 剪贴板 API。因此,您可以使用 BMP,但不能使用。
image.convert("RGB").save(output, "PNG")
data = output.getvalue()[8:]

即使你知道PNG的偏移量是8。

1

这在Python 3.8中对我有效(解决方案在此处找到

这与cgohike的答案相同,但有一点不同:

output = StringIO()

转换为:

output = io.BytesIO()

完整代码:

代码:

import io
import win32clipboard
from PIL import Image

def send_to_clipboard(clip_type, data):
    win32clipboard.OpenClipboard()
    win32clipboard.EmptyClipboard()
    win32clipboard.SetClipboardData(clip_type, data)
    win32clipboard.CloseClipboard()

image = Image.open('image.jpg')

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

send_to_clipboard(win32clipboard.CF_DIB, data)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接