如何使用Python在操作系统剪贴板中添加/获取图像数据?

如何使用Python在操作系统剪贴板中添加/获取图像数据?,python,python-3.x,clipboard,clipboarddata,Python,Python 3.x,Clipboard,Clipboarddata,我有一些编辑图像文件的Python代码,我想知道如何 将图像数据添加到操作系统剪贴板并从中获取 搜索跨平台解决方案以替换或获取Python中的剪贴板文本时, 有许多简单的解决方法(例如使用内置的Tkinter模块)。 但是,这些方法只能使用纯文本,而不能使用其他剪贴板数据(如图像) 我的Python版本在Windows上是3.x,但答案必须是跨平台的 (在不同的操作系统上工作)并且还应该支持其他Python版本,如2.x。 我认为它应该只使用内置的Python模块,并且代码不应该太复杂(或者解释

我有一些编辑图像文件的Python代码,我想知道如何
将图像数据添加到操作系统剪贴板并从中获取

搜索跨平台解决方案以替换或获取Python中的剪贴板文本时,
有许多简单的解决方法(例如使用内置的Tkinter模块)。
但是,这些方法只能使用纯文本,而不能使用其他剪贴板数据(如图像)

我的Python版本在Windows上是3.x,但答案必须是跨平台的
(在不同的操作系统上工作)并且还应该支持其他Python版本,如2.x。
我认为它应该只使用内置的Python模块,并且代码不应该太复杂(或者解释它的功能)。它可以是Python模块,因为文件可以与可移植程序代码包含在同一文件夹中,以避免安装

还有一些与此相关的问题可能适用于图像,但它们只支持单个操作系统。最好的是和。
此处描述的方法(仅适用于Windows)似乎使用以下步骤:

  • 获取图像的原始二进制数据-该方法加载带有Python映像的图像文件
    Library()模块,因为它具有稍后使用的其他处理功能,使用简单的
    和流行的标准API。这可以用另一个模块代替(例如Pygame)
  • 使用内置io创建文件对象变量(用于内存中的输入/输出流)
    模块。对于Python2.x,使用cStringIO import StringIO中的
    ,但是对于Python3,使用
    使用更好的
    io.BytesIO
    二进制流对象类型-较旧的类型现在只允许文本
  • 以BMP(Windows位图/设备独立位图)文件格式保存图像数据,
    到上一步中的文件对象变量。使用PIL/枕头的方法首先转换
    此数据在包含它的变量上使用
    .convert(“RGB”)
  • 以二进制数据的形式获取文件对象变量内存缓冲区的全部内容(
    bytes
    object),
    从位置14切片,删除BMP/DIB文件格式的14字节头,然后保存
    作为一个变量。该方法表示,该数据的切片可以在32位或64位系统上工作,但
    需要Windows剪贴板API,因此不适用于其他文件格式
  • 关闭内存缓冲区并将上一步的图像数据复制到剪贴板。
    此方法在Windows上使用扩展模块的
    win32clipboard
    部分执行此操作-
    它打开剪贴板供使用,清除剪贴板,将其值设置为来自
    上一步(使用BMP/DIB类型)然后关闭打开的剪贴板
还有一个简单的跨平台剪贴板文本模块,名为

1.5.6版只有一个,可能有可以处理图像数据的代码。

我认为没有外部模块,您无法与剪贴板交互

剪贴板API因操作系统而异

我建议您使用剪贴板模块

如马丁所述---

Pyperclip绝对是一个不错的选择,它的工作方式很有魅力

我不知道你为什么不应该用它

它只需下面三行

import pyperclip
pyperclip.copy('The text to be copied to the clipboard.')
paste= pyperclip.paste()

xerox
库简单且功能强大

这是一个基于的Python函数,它使用Tkinter替换/返回剪贴板文本。

此方法创建一个快速隐藏的窗口,该窗口将快速关闭,因此
这不应该是个问题。而且,它只支持在
剪贴板,而不是我在上面问题中要求的图像

问题:如何使用Python在操作系统剪贴板中添加/获取图像数据

我只显示获取
此示例使用内置的Tkinter模块从
剪贴板获取图像数据

仅在Linux上测试,但应为跨平台解决方案

注意:所示387x388 GIF的第一次粘贴需要4秒钟


核心点:必须使用MIME类型才能请求图像

.clipboard_get(type='image/png')
使用应用程序,
GIMP
PyCharm
验证为源图像数据,
'GIF'
'PNG'
。使用
type='image/png'
如果源应用程序支持此功能,您将始终获得
'png'
类型的图像数据


参考

0x89 0x50 0x4e 0x47 0xd 0xa 0x1a 0xa 0x0 0x0 0x0 0xd 0x49 0x48 0x44
  • 从剪贴板检索数据。类型指定返回数据的形式,并且应为原子名称,如字符串或文件名。在现代X11系统上,将默认值键入UTF8_字符串


数据格式

0x89 0x50 0x4e 0x47 0xd 0xa 0x1a 0xa 0x0 0x0 0x0 0xd 0x49 0x48 0x44
数据被划分为用空格分隔的字段;每个字段都转换为其原子值,并传输32位原子值而不是原子名称

删除空白并使用
int(,0)
进行强制转换后:



用Python测试:3.5-“TclVersion”:8.6“TkVersion”:8.6

您试图在什么操作系统上执行此操作?对您不起作用?您甚至尝试过此功能吗?如果将其放入脚本中并运行脚本,则窗口打开的时间不够长,甚至不会引起注意。@Burnkhalid Pyperclip是“跨平台剪贴板模块”,是一个单独的文件,可以与程序代码包含在同一文件夹中,以避免安装它,但是Tkinter解决方案使用Python内置的代码。另外,它目前只处理纯文本,因此不能用于剪贴板中的图像(我的第二个请求)。@JohnY我在一两年前查看了你的评论,并接受了基于Tkinter的替换/返回剪贴板文本的解决方案。有关使用该内置模块的简单Python函数,请参见下面的答案。然而,它只处理pla
bytearray(b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHD...')
<PIL.PngImagePlugin.PngImageFile image mode=P size=387x388 at 0xF555E20C>
TclError:CLIPBOARD selection doesn't exist or form "image/png" not defined

import tkinter as tk
from PIL import Image, ImageTk
import io


class App(tk.Tk):
    def __init__(self):
        super().__init__()  # options=(tk.Menu,))
        self.menubar = tk.Menu()
        self.config(menu=self.menubar)
        self.menubar.add_command(label='paste', command=self.on_paste)
        
        self.label = tk.Label(self, text="CLIPBOARD image", font=("David", 18),
                              image='', compound='center')
        self.label.grid(row=0, column=0, sticky='w')

    def on_paste(self):
        self.label.configure(image='')
        self.update_idletasks()
        
        try:
            b = bytearray()
            h = ''
            for c in self.clipboard_get(type='image/png'):
                if c == ' ':
                    try:
                        b.append(int(h, 0))
                    except Exception as e:
                        print('Exception:{}'.format(e))
                    h = ''
                else:
                    h += c

        except tk.TclError as e:
            b = None
            print('TclError:{}'.format(e))
        finally:
            if b is not None:
                with Image.open(io.BytesIO(b)) as img:
                    print('{}'.format(img))
                    self.label.image = ImageTk.PhotoImage(img.resize((100, 100), Image.LANCZOS))
                    self.label.configure(image=self.label.image)