导读
临时有个需求,需要操作下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()