2011-08-12 38 views
9

Tengo una imagen (jpg, png, etc.) en el portapapeles de Windows. Me gustaría guardarlo en un archivo. win32clipboard parece ser la respuesta, pero cada ejemplo que puedo encontrar trata de texto.¿Cómo leo un jpg o png desde el portapapeles de Windows en python y viceversa?

copiar una imagen en el portapapeles, a continuación,

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

falla con

TypeError: Specified clipboard format is not available 

También me gustaría hacer lo contrario - dado un archivo de imagen, escribir en el portapapeles.

+1

Si usted está abierto a utilizar el módulo WX que podría hacer: http://stackoverflow.com/preguntas/2629907/WX-imagen-lectura del portapapeles- – blcArmadillo

+0

estoy intentando escribir una utilidad de línea de comandos simple, y actualmente no usar wx, por lo que prefiero no ir allí. – foosion

Respuesta

16

me acaba de utilizar Pillow:

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

Solo estaba viendo eso, pero necesito tanto Python 2.7 como 3.2 y PIL no parece disponible para 3.2 – foosion

+0

@foosion: Creo que hay un binario precompilado para Python 3.2 aquí: http: //www.lfd .uci.edu/~ gohlke/pythonlibs/ – Gerrat

+0

Esto es muy simple para 2.7. Esperaba que agregar algunas líneas a la versión de win32clipboard funcionaría así. – foosion

4

La función win32clipboard.GetClipboardData() tiene un parámetro. El parámetro predeterminado especifica que desea el contenido del portapapeles como texto. Debe ingresar el valor que especifica el formato de datos que desea que le proporcione el portapapeles.

Los formatos de datos estándar del portapapeles se documentan here.

también:

Ver here de documentación sobre EnumClipboardFormats() - básicamente, es necesario un código como éste (no probado) para obtener los formatos que están disponibles actualmente en el portapapeles:

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

he intentado enumerar formatos y tiene 49353, 0, 8, 0, 0, 0, 0, 17, 0. No acabo de usar 49353? win32clipboard.OpenClipboard (49353) genera un error: (1400, 'OpenClipboard', 'Identificador de ventana inválido') – foosion

+0

¿Vio la página con documentación sobre los códigos de formato? 8 es 'BITMAPINFO' y 7 es' BITMAPV5HEADER', ambos incluyen los datos del mapa de bits. Es posible que necesite aprender más sobre cómo Windows maneja las imágenes de lo que desea ... – bgporter

+0

Ninguno de los códigos enumerados en http://msdn.microsoft.com/en-us/library/ff729168(v=VS.85) .aspx llega tan alto como 49353. El siguiente valor es 8, que es la estructura BITMAPINFO, pero no tengo claro qué hacer con él – foosion

4

Debe pasar un parámetro al GetClipboardData especificando el formato de los datos que está buscando. Puede usar EnumClipboardFormats para ver los formatos que están disponibles: cuando copio algo en el Explorador, hay 15 formatos disponibles para mí.

Edición 2: Aquí está el código para obtener un nombre de archivo después de que haya copiado un archivo en el Explorador. La respuesta será completamente diferente si ha copiado una imagen desde un programa, un navegador, por ejemplo.

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

Datos 3: A partir de los comentarios está claro que tiene una imagen real en el portapapeles, no el nombre de archivo de un archivo de imagen. Usted ha declarado que no se puede utilizar PIL, por lo que:

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

En este punto usted tiene una cadena (en Python 2) o bytes (en Python 3) que contiene los datos de la imagen. El único formato que será capaz de ahorrar es .BMP, y que tendrá que descifrar el BITMAPINFOHEADER para obtener los parámetros para un BITMAPFILEHEADER que necesita ser escrita en la parte delantera del archivo.

+0

Puedo crear un nombre de archivo por mi cuenta. ¿Ciclo a través de EnumClipboardFormats() comenzando con 0? ¿Qué hago con los resultados? – foosion

+0

@foosion, ¿puede explicar exactamente qué hay en el portapapeles? ¿Hiciste una Copia en una imagen que se muestra en un programa, o en un nombre de archivo en el Explorador? –

+0

Mis pruebas actuales son copiar una imagen de una página en un navegador web y desde un programa de pintura. Además, por favor, consulte mi comentario a bgporter – foosion

2

Usando PythonMagick (binaries):

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

Parece prometedor e incluso admite archivos clip-> y archivo-> clip. – foosion

Cuestiones relacionadas