2011-08-12 43 views
9

我在Windows剪贴板中有一个图像(JPG,PNG等)。我想将它保存到一个文件中。 win32clipboard似乎是答案,但我可以找到的每个例子都与文本有关。如何从python的windows剪贴板中读取jpg或png,反之亦然?

的图像复制到剪贴板,然后

import win32clipboard 
win32clipboard.OpenClipboard() 
data = win32clipboard.GetClipboardData() 
with open(name, 'wb') as f: 
    f.write(data) 
win32clipboard.CloseClipboard() 

失败

TypeError: Specified clipboard format is not available 

我也想这样做相反 - 给出一个图像文件,将其写入到剪贴板。

+1

如果你打开使用WX模块,你可以这样做:http://stackoverflow.com/questions/2629907/wx-read-image-from-clipboard – blcArmadillo

+0

我想写一个简单的命令行工具,并且目前不使用wx,所以我宁愿不去那里。 – foosion

回答

16

我只想用Pillow

from PIL import ImageGrab 
im = ImageGrab.grabclipboard() 
im.save('somefile.png','PNG') 
+0

我只是看着那个,但我需要Python 2.7和3.2,PIL似乎不可用于3.2 – foosion

+0

@foosion:我认为这里有一个预编译的二进制python 3.2:http://www.lfd .uci.edu /〜gohlke/pythonlibs/ – Gerrat

+0

这对2.7来说很简单。我希望在win32clipboard版本中添加几行就可以这样工作。 – foosion

4

功能win32clipboard.GetClipboardData()有一个参数。默认参数指定您希望将剪贴板的内容作为文本。您需要传入指定您希望剪贴板给您的数据格式的值。

标准剪贴板数据格式记录在here

ALSO:

here的文档上EnumClipboardFormats() - 基本上,你需要这样的(未经测试)代码以获取可用当前剪贴板上的格式:

formats = [] 
lastFormat = 0 
while 1: 
    nextFormat = win32clipboard.EnumClipboardFormats(lastFormat) 
    if 0 == nextFormat: 
     # all done -- get out of the loop 
     break 
    else: 
     formats.append(nextFormat) 
     lastFormat = nextFormat 
# when you get here, formats contains a list of format codes that 
# you can retrieve from the clipboard right now. 
+0

我只是试过枚举格式,得到了49353,0,8,0,0,0,0,17,0。我只用49353吗? win32clipboard。OpenClipboard(49353)导致错误:(1400,'OpenClipboard','无效的窗口句柄') – foosion

+0

您是否看到包含格式代码文档的页面? 8是“BITMAPINFO”,7是“BITMAPV5HEADER”,它们都包含位图数据。您可能最终需要了解有关Windows如何处理图像的更多信息,而不是您想要的... – bgporter

+0

http://msdn.microsoft.com/zh-cn/library/ff729168(v = VS.85 ).aspx高达49353.下一个值是8,这是BITMAPINFO结构,但我不清楚如何处理它 – foosion

4

您需要将参数传递给GetClipboardData,以指定要查找的数据的格式。您可以使用EnumClipboardFormats查看可用的格式 - 当我在资源管理器中复制某些内容时,我可以使用15种格式。

编辑2:下面是在您将文件复制到资源管理器后获取文件名的代码。如果您从程序内部复制图像,例如浏览器,答案将完全不同。

import win32clipboard 
win32clipboard.OpenClipboard() 
filename_format = win32clipboard.RegisterClipboardFormat('FileName') 
if win32clipboard.IsClipboardFormatAvailable(filename_format): 
    input_filename = win32clipboard.GetClipboardData(filename_format) 
win32clipboard.CloseClipboard() 

编辑3:从评论很明显,你在剪贴板中有一个实际的图像,图像文件的不是文件名。你说,你不能使用PIL,所以:

import win32clipboard 
win32clipboard.OpenClipboard() 
if win32clipboard.IsClipboardFormatAvailable(win32clipboard.CF_DIB): 
    data = win32clipboard.GetClipboardData(win32clipboard.CF_DIB) 
win32clipboard.CloseClipboard() 

此时你有一个包含图像数据的字符串(在Python 2)或字节(在Python 3)。唯一可以保存的格式是.BMP,并且您必须解码BITMAPINFOHEADER以获取需要写入文件前面的BITMAPFILEHEADER的参数。

+0

我可以自己创建一个文件名。我是否通过从0开始的EnumClipboardFormats()循环?我如何处理结果? – foosion

+0

@foosion,你能详细说明剪贴板中的内容吗?您是否在程序中显示的图像上或文件夹中的文件名上进行了复制? –

+0

我目前的测试是从Web浏览器中的页面和绘图程序中复制图像。另外,请看我对bgporter – foosion

2

使用PythonMagickbinaries):

from PythonMagick import Image 
Image("clipboard:").write("PNG32:clipboard.png") # clipboard -> file 
Image("clipboard.png").write("clipboard:") # file -> clipboard 
+0

看起来很有前途,甚至支持剪辑 - >文件和文件 - >剪辑。 – foosion

相关问题