吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1072|回复: 11
收起左侧

[求助] python有办法将PNG和GIF等导入剪贴板吗

[复制链接]
Sucaiking 发表于 2023-7-24 19:57
本帖最后由 Sucaiking 于 2023-7-24 20:31 编辑

我写了个表情包复制器,给它一个目录,它可以列出目录下一层的文件夹,也能列出选定文件夹里的表情,点击即可复制到剪贴板。
但我只做出来BMP格式的复制,无法应对alpha通道,也无法处理gif。希望能改进copy_to_clipboard这个函数,使之能支持更多的功能。换其他库也行。
我先把自己的代码拿上来抛砖引玉,希望有大佬可以帮忙解答,感激不尽。

    def copy_to_clipboard(self, idx):
        image = Image.open(self.image_paths[idx])
        output = io.BytesIO()
        image.save(output, format="BMP")
        win32clipboard.OpenClipboard()
        win32clipboard.EmptyClipboard()
        win32clipboard.SetClipboardData(win32con.CF_DIB, output.getvalue()[14:])
        win32clipboard.CloseClipboard()

        # Provide feedback: Highlight the image with a border for 0.2 seconds
        item = self.canvas.find_withtag("current")[0]
        self.canvas.create_rectangle(self.canvas.bbox(item), outline="red", tags="highlight")
        self.root.after(120, lambda: self.canvas.delete("highlight"))


QQ图片20230724195601.png

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

梦汐 发表于 2023-7-24 21:04
[Asm] 纯文本查看 复制代码
import pyperclip

def copy_image_to_clipboard(image_path):
    with open(image_path, 'rb') as image_file:
        image_data = image_file.read()
        pyperclip.copy(image_data)
        print('图像已成功复制到剪贴板!')

# 示例使用,将图片路径替换为实际的PNG或GIF图像路径
image_path = 'path/to/image.png'
copy_image_to_clipboard(image_path)
 楼主| Sucaiking 发表于 2023-7-24 21:17
梦汐 发表于 2023-7-24 21:04
[mw_shl_code=asm,true]import pyperclip

def copy_image_to_clipboard(image_path):

这个方法我也试过了。那时我得到了这样一个报错,非常奇怪:
pyperclip.PyperclipException: only str, int, float, and bool values can be copied to the clipboard, not bytes

不过我发现读到的路径长这样:“D:/.../文件夹A\文件夹B\文件名.png”,我在想这会不会是问题之一。
梦汐 发表于 2023-7-24 21:26
Sucaiking 发表于 2023-7-24 21:17
这个方法我也试过了。那时我得到了这样一个报错,非常奇怪:
[md]```
pyperclip.PyperclipException: o ...

不支持字节,用clip也行,
import win32clipboard as clip
    clip.OpenClipboard()
    clip.EmptyClipboard()
    clip.SetClipboardData(win32con.CF_DIB, 数据)
    clip.CloseClipboard()

 楼主| Sucaiking 发表于 2023-7-24 21:58
梦汐 发表于 2023-7-24 21:26
不支持字节,用clip也行,
import win32clipboard as clip
    clip.OpenClipboard()

这就是我最初的代码呀……除了用14大法处理bmp,其他没有成功的。
lyjccmm 发表于 2023-7-24 22:43
本帖最后由 lyjccmm 于 2023-7-24 22:46 编辑

既然楼主说换其他库也行,那就直接用pyqt库就好了

pyqt库里面的接口天然支持剪切板与图片的各种写入和读取

QMimeData类提供一个容器,用于数据记录有关它的MIME类型的信息。

QMimeData是用来描述可以存储在信息clipboard,并经由传输drag and drop机制。 QMimeData对象,它们与相应的MIME类型保存数据关联起来,以确保信息可以在应用程序之间进行安全转移,并在同一应用程序内各地复制。

对于最常见的MIME类型, QMimeData提供方便的功能来访问数据:

  • Tester
    • hasText()
    • hasHtml()
    • hasUrls()
    • hasImage()
    • hasColor()
  • Getter
    • text()     
    • html()     
    • urls()     
    • imageData()
    • colorData()
  • Setter
    • setText()     
    • setHtml()     
    • setUrls()     
    • setImageData()
    • setColorData()
  • MIME Types
    • text/plain         
    • text/html         
    • text/uri-list      
    • image/ *           
    • application/x-color

关于自定义类型

在Windows上,formats() 也将返回的MIME数据可自定义格式,使用x-qt-windows-mime亚型,表明它们代表了非标准格式的数据。该格式将采取以下形式:

application/x-qt-windows-mime;value="<custom type>"

比如我在vscode复制后,调用formats()显示如下:(换行是我自己加的)

['application/x-qt-windows-mime;value="Shell IDList Array"',
'application/x-qt-windows-mime;value="DataObjectAttributes"',
'application/x-qt-windows-mime;value="DataObjectAttributesRequiringElevation"',
'application/x-qt-windows-mime;value="Shell Object Offsets"',
'application/x-qt-windows-mime;value="Preferred DropEffect"',
'application/x-qt-windows-mime;value="AsyncFlag"',
'text/uri-list',
'application/x-qt-windows-mime;value="FileName"',
'application/x-qt-windows-mime;value="FileContents"',
'application/x-qt-windows-mime;value="FileNameW"',
'application/x-qt-windows-mime;value="FileGroupDescriptorW"']

样例测试,(测试方法就是,先复制一个东西,然后运行这段代码,就可以清楚的看到剪切板里面有什么内容了)

import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QClipboard

app = QApplication(sys.argv)
cb = QApplication.clipboard()
print(cb.mimeData(QClipboard.Mode.Clipboard).formats())
if cb.mimeData().hasColor():
    print("hasColor")
if cb.mimeData().hasImage():
    print("hasImage")
    # qt_img = cb.image()
    qt_img = cb.mimeData().imageData()
    print(qt_img)
if cb.mimeData().hasHtml():
    print("hasHtml")
    print(cb.mimeData().html())
if cb.mimeData().hasText():
    print("hasText")
    print(cb.mimeData().text())
    # print(cb.text())
if cb.mimeData().hasUrls():
    print("hasUrls")
    print(cb.mimeData().urls())

其他接口可以看官方文档

至于如何复制一个图片进剪切板,我给你一个代码参考,可以直接运行的(代码里面有一段读取./images/python.png位置的图片需要你自己修改位置)

import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class ClipBoard(QDialog):
    def __init__(self):
        super(ClipBoard,self).__init__()
        textCopyButton = QPushButton('复制文本')
        textPasteButton = QPushButton('粘贴文本')

        htmlCopyButton = QPushButton('复制HTML')
        htmlPasteButton = QPushButton('粘贴HTML')

        imageCopyButton = QPushButton('复制图像')
        imagePasteButton = QPushButton('粘贴图像')

        self.textLabel  = QLabel('默认文本')
        self.imageLabel=QLabel()
      #  self.imageLabel.setPixmap(QPixmap('./images/python.png'))

        layout = QGridLayout()
        layout.addWidget(textCopyButton,0,0)
        layout.addWidget(imageCopyButton,0,1)
        layout.addWidget(htmlCopyButton,0,2)
        layout.addWidget(textPasteButton,1,0)
        layout.addWidget(htmlPasteButton,1,1)
        layout.addWidget(imagePasteButton,1,2)

        layout.addWidget(self.textLabel,2,0,1,2)
        layout.addWidget(self.imageLabel,2,2)

        self.setLayout(layout)

        textCopyButton.clicked.connect(self.copyText)

        textPasteButton.clicked.connect(self.pasteText)
        htmlCopyButton.clicked.connect(self.copyHtml)
        htmlPasteButton.clicked.connect(self.pasteHtml)
        imageCopyButton.clicked.connect(self.copyImage)
        imagePasteButton.clicked.connect(self.pasteImage)

        self.setWindowTitle('剪贴板演示')

    def copyText(self):
        clipboard = QApplication.clipboard()
        clipboard.setText('hello world')
    def pasteText(self):
        clipboard = QApplication.clipboard()
        self.textLabel.setText(clipboard.text())

    def copyImage(self):
        clipboard = QApplication.clipboard()
        clipboard.setPixmap(QPixmap('./images/python.png'))

    def pasteImage(self):
        clipboard = QApplication.clipboard()
        self.imageLabel.setPixmap(clipboard.pixmap())

    def copyHtml(self):
        mimeData = QMimeData()
        mimeData.setHtml('<b>Bold and <font color=red>Red</font></b>')
        clipboard = QApplication.clipboard()
        clipboard.setMimeData(mimeData)

    def pasteHtml(self):
        clipboard = QApplication.clipboard()
        mimeData = clipboard.mimeData()
        if mimeData.hasHtml():
            self.textLabel.setText(mimeData.html())

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = ClipBoard()
    main.show()
    sys.exit(app.exec_())
burning 发表于 2023-7-24 23:23
lyjccmm 发表于 2023-7-24 22:43
[md]既然楼主说换其他库也行,那就直接用pyqt库就好了

pyqt库里面的接口天然支持剪切板与图片的各种写入 ...

能复制文件夹吗
burning 发表于 2023-7-24 23:34
Sucaiking 发表于 2023-7-24 21:58
这就是我最初的代码呀……除了用14大法处理bmp,其他没有成功的。

14大法是什么
lyjccmm 发表于 2023-7-25 00:06
burning 发表于 2023-7-24 23:23
能复制文件夹吗

你说的这个其实可以归类为复制文件

复制文件与复制图片是有本质区别的,复制文件都只是复制了操作系统上的路径,复制文件夹也是同理,实际上写入剪切板的是文件夹的路径

比如我复制我自己桌面上的文件夹,名字叫t,我windows的用户名叫lyjcc,所以文件夹的路径是C:/Users/lyjcc/Desktop/t

然后用我刚刚前面发的测试代码实验一下,得到的输出显示如下

['application/x-qt-windows-mime;value="Shell IDList Array"', 'application/x-qt-windows-mime;value="DataObjectAttributes"', 'application/x-qt-windows-mime;value="DataObjectAttributesRequiringElevation"
', 'application/x-qt-windows-mime;value="Shell Object Offsets"', 'application/x-qt-windows-mime;value="Preferred DropEffect"', 'application/x-qt-windows-mime;value="AsyncFlag"', 'text/uri-list', 'appl
ication/x-qt-windows-mime;value="FileName"', 'application/x-qt-windows-mime;value="FileNameW"']
hasText
file:///C:/Users/lyjcc/Desktop/t
hasUrls
[PyQt5.QtCore.QUrl('file:///C:/Users/lyjcc/Desktop/t')]

可以看到,常用的几个剪切板类型里面含有text文本信息,信息就是文件的路径,同时还有一个url信息,url信息也是对应文件夹的路径

除此之外,在我打印出里面所有的内容,还有很多自定义的剪切板类型,都是windows系统自检定义的类型

奥怪 发表于 2023-7-25 00:36
本帖最后由 奥怪 于 2023-7-25 00:38 编辑

试试我的?
可以操作剪贴板中的文件路径、图像数据和文本。支持(批量)设置和读取文件路径列表、图像数据和文本,以及判断文件是否为图像等功能。
文字、图片、文件都支持,支持粘贴到QQ和VX。
aoguai/ClipboardManage: ClipboardManage 是一个用于操作 Windows 剪贴板的 Python 轻量工具类。ClipboardManage is a lightweight Python utility class for manipulating the Windows clipboard.
https://github.com/aoguai/ClipboardManage
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 21:32

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表