python 往win10剪贴板塞入文字和图片(本地图片、远程图片)记录

导读

临时有个需求,需要操作下win10电脑下的剪贴板,我们需要往这个剪贴板中塞入我们的文字信息和图片资源,当然图片资源包括本地资源和远程资源,查阅了一些文档,发现都比较凌乱,这里呢,简单总结下。

1. 需要的几个包

# 需要载入的模块包
import win32con
from PIL import Image
import win32clipboard as w
from io import BytesIO
from urllib import request

2. 剪贴板类型

这里呢,我们往剪贴板塞入内容需要设置的内容的类型,Windows支持不同的预先定义剪切板格式,这些格式在WINDOWS.INC定义成以CF为前缀的标识符,总共有哪些类型标识符呢,如下展示:

  • CF_TEXT以NULL 结尾的ANSI字符集字符串。它在每行末尾包含一个carriage return和linefeed字符,这是最简单的剪切板数据格式。传送到剪切板的数据存放在整体内存块中,并且是利用内存块句柄进行传送的(我将简短地讨论此项概念)。这个内存块专供剪切板使用,建立它的程序不应该继续使用它。

  • CF_OEMTEXT 含有文字数据(与CF_TEXT类似)的内存块。但是它使用的是OEM字符集。通常Windows程序不必关心这一点;它只有与在窗口中执行MS-DOS程序一起使用剪切板时才会使用。

  • CF_UNICODETEXT 含有Unicode文字的内存块。与CF_TEXT类似,它在每一行的末尾包含一个carriage return和linefeed字符,以及一个NULL字符(两个0字节)以表示数据结束。CF_UNICODETEXT只支援Windows NT。

  • CF_LOCALE 一个国家地区标识符的句柄。表示剪切板文字使用的国别地区设定。

下面是两种附加的剪切板格式,它们在概念上与CF_TEXT格式相似(也就是说,它们都是文字数据),但是它们不需要以NULL结尾,因为格式已经定义了数据的结尾。现在已经很少使用这些格式了:

  • CF_SYLK包含Microsoft 「符号连结」数据格式的整体内存块。这种格式用在Microsoft的Multiplan、Chart和Excel程序之间交换数据,它是一种ASCII码格式,每一行都用carriage return和linefeed结尾。
  • CF_DIF包含数据交换格式(DIF)之数据的整体内存块。这种格式是由Software Arts公司提出的,用于把数据送到VisiCalc电子表格程序中。这也是一种ASCII码格式,每一行都使用carriage return和linefeed结尾。

下面三种剪切板格式与位图有关。所谓位图就是数据位的矩形数组,其中的数据位与输出设备的图素相对应。后面将详细讨论位图以及这些位图剪切板的格式:

  • CF_BITMAP与设备相关的位图格式。位图是通过位图句柄传送给剪切板的。同样,在把这个位图传送给剪切板之后,程序不应该再继续使用这个位图。
  • CF_DIB定义一个设备无关位图的内存块。这种内存块是以位图信息结构开始的,后面跟着可用的颜色表和位图数据位。
  • CF_PALETTE调色盘句柄。它通常与CF_DIB配合使用,以定义与设备相关的位图所使用的颜色调色盘。

在剪切板中,还有可能以工业标准的TIFF格式储存的位图数据:

  • CF_TIFF含有标号图像文件格式(TIFF)数据的整体内存块。这种格式由Microsoft、Aldus公司和Hewlett-Packard公司以及一些硬件厂商推荐使用。这一格式可从Hewlett-Packard的网站上获得。

下面是两个metafile格式。一个metafile就是一个以二进制格式储存的画图命令集:

  • CF_METAFILEPICT以旧的metafile格式存放的「图片」。
  • CF_ENHMETAFILE增强型metafile(32位Windows支持的)句柄。

最后介绍几个混合型的剪切板格式:

  • CF_PENDATA与Windows的笔式输入扩充功能联合使用。
  • CF_WAVE声音(波形)文件。
  • CF_RIFF使用资源交换文件格式(Resource Interchange File Format)的多媒体数据。
  • CF_HDROP与拖放服务相关的文件列表。

有需要的同学,可以在上面的看列表中,找到合适的标志符,再传递对应的数据内容

方法封装

下面呢,我封装了几个常用的剪切板使用,以及获取图片资源(远程、本地)的方法,方便于后续进行项目的延展性开发

# 读取本地图片内容
def getLocalImageData(path):
    img = Image.open(path)
    output = BytesIO()  # BytesIO实现了在内存中读写bytes
    img.convert("RGB").save(output, "BMP") #以RGB模式保存图像
    data = output.getvalue()[14:]
    output.close()
    return data

# 读取互联网远程的图片内容
def getNetImageData(netUrl):
    file = BytesIO(request.urlopen(netUrl).read())
    img = Image.open(file)
    output = BytesIO()  # BytesIO实现了在内存中读写bytes
    img.convert("RGB").save(output, "BMP") #以RGB模式保存图像
    data = output.getvalue()[14:]
    output.close()
    return data

# 把 Pillow/PIL Image object 塞入剪贴板
def getPILImageData(img):
    output = BytesIO()  # BytesIO实现了在内存中读写bytes
    img.convert("RGB").save(output, "BMP") #以RGB模式保存图像
    data = output.getvalue()[14:]
    output.close()
    return data

# 把图片内容塞入剪贴板
def setImageDataToClipboard(data):
    w.OpenClipboard()
    w.EmptyClipboard()
    w.SetClipboardData(win32con.CF_DIB, data)
    w.CloseClipboard()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章