6

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

在寻找跨平台解决方案来替换或获取Python 中的剪贴板文本时,有很多简单的答案(例如,使用带有一些代码
的内置 Tkinter 模块)。 但是,这些方法只能使用纯文本,不能使用其他剪贴板数据,如图像。

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

还有一些其他相关问题可能适用于图像,但它们仅支持单个操作系统。最好的是将图像复制到 Python3 中的剪贴板和使用 PIL和win32clipboard 在 python 中将图像写入 Windows 剪贴板?.
那里描述的方法(仅适用于 Windows)似乎使用以下步骤:

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

此外,还有一个名为Pyperclip的简单跨平台剪贴板文本模块,它
只是 1.5.6 版本的单个文件,并且可能包含可以处理图像数据的代码。

4

5 回答 5

1

问题:如何使用 Python 在 OS 剪贴板中添加/获取图像数据?

我只展示了get
这个例子是使用内置的 Tkinter 模块从CLIPBOARD.
仅在Linux上测试,但应该是一个跨平台的解决方案。

在此处输入图像描述 在此处输入图像描述

注意:paste显示的 387x388 GIF 中的第一个需要 4 秒。


核心点:您必须使用 MIME-Type 来请求图像。

.clipboard_get(type='image/png')

使用应用程序和,和'GIF',作为源图像数据进行验证 如果源应用程序支持,您总是可以获得类型的图像数据。'PNG''JPEG'GIMPPyCharmtype='image/png''PNG'


参考

  • clippboard_get(type=<string>)

    从剪贴板中检索数据。类型指定返回数据的形式,应该是原子名称,例如 STRING 或 FILE_NAME。现代 X11 系统上的默认类型为 UTF8_STRING。


数据格式

0x89 0x50 0x4e 0x47 0xd 0xa 0x1a 0xa 0x0 0x0 0x0 0xd 0x49 0x48 0x44

数据被分成由空格分隔的字段;每个字段都转换为其原子值,并传输 32 位原子值而不是原子名称。

删除空白区域并使用以下命令进行转换后int(<field>, 0)

bytearray(b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHD...')
<PIL.PngImagePlugin.PngImageFile image mode=P size=387x388 at 0xF555E20C>

例外:如果根本没有选择或源应用程序不提供'image/png'

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)

用 Python 测试:3.5 - 'TclVersion':8.6 'TkVersion':8.6

于 2020-01-22T15:16:45.147 回答
0

xerox库简单且功能强大。

于 2014-08-31T13:39:59.297 回答
0

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

def use_clipboard(paste_text=None):
    import tkinter # For Python 2, replace with "import Tkinter as tkinter".
    tk = tkinter.Tk()
    tk.withdraw()
    if type(paste_text) == str: # Set clipboard text.
        tk.clipboard_clear()
        tk.clipboard_append(paste_text)
    try:
        clipboard_text = tk.clipboard_get()
    except tkinter.TclError:
        clipboard_text = ''
    r.update() # Stops a few errors (clipboard text unchanged, command line program unresponsive, window not destroyed).
    tk.destroy()
    return clipboard_text

此方法创建一个快速隐藏的窗口,该窗口会快速关闭,因此
不应该成为问题。此外,它只支持在
剪贴板中使用纯文本,而不是我在上面的问题中要求的图像。

于 2014-09-27T16:26:09.263 回答
0

我认为如果没有外部模块,您将无法与剪贴板进行交互。

剪贴板 API 与不同的操作系统不同。

我建议你使用剪贴板模块。

https://pypi.python.org/pypi/clipboard/0.0.4

于 2014-06-29T08:57:05.450 回答
-1

正如马丁所说——

Pyperclip 绝对是一个不错的选择,它的作用就像一个魅力。

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

它就像下面的3行一样简单,

import pyperclip
pyperclip.copy('The text to be copied to the clipboard.')
paste= pyperclip.paste()
于 2014-06-29T21:10:05.750 回答