2011-08-12 20 views
9

Mam obraz (jpg, png, itp.) W schowku systemu Windows. Chciałbym zapisać go w pliku. Win32clipboard wydaje się być odpowiedzią, ale każdy przykład mogę znaleźć oferty z tekstem.Jak odczytać plik jpg lub png ze schowka Windows w pythonie i na odwrót?

skopiować obraz do schowka, a następnie

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

nie z

TypeError: Specified clipboard format is not available 

Chciałbym też zrobić odwrotnie - dany plik obrazu, zapisz go do schowka.

+1

Jeśli jesteś otwarty na zastosowanie modułu wx mógłby zrobić: http://stackoverflow.com/questions/2629907/wx-read-image-from-clipboard – blcArmadillo

+0

Próbuję napisać proste narzędzie wiersza poleceń i nie używam obecnie polecenia wx, więc wolałbym tam nie iść. – foosion

Odpowiedz

16

Chciałbym po prostu użyć Pillow:

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

Po prostu na to patrzę, ale potrzebuję zarówno Pythona 2.7 i 3.2, jak i PIL nie wydaje się dostępny dla 3.2 – foosion

+0

@foosion: Myślę, że jest prekompilowany plik binarny dla Pythona 3.2 tutaj: http: //www.lfd .uci.edu/~ gohlke/pythonlibs/ – Gerrat

+0

To jest proste dla 2.7. Miałem nadzieję, że dodanie kilku linii do wersji win32clipboard będzie działać w ten sposób. – foosion

4

Funkcja win32clipboard.GetClipboardData() ma parametr. Domyślny parametr określa, że ​​zawartość schowka ma być tekstem. Musisz podać wartość, która określa format danych, który ma otrzymać schowek.

Standardowe formaty danych schowka są udokumentowane here.

TAKŻE:

Zobacz here dokumentacji na EnumClipboardFormats() - w zasadzie, trzeba kod podobny do tego (nietestowanego) dostać formatów, które są dostępne obecnie w schowku:

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

Po prostu próbowałem wyliczyć formaty i otrzymałem 49353, 0, 8, 0, 0, 0, 0, 17, 0. Czy używam tylko 49353? win32clipboard.OpenClipboard (49353) powoduje błąd: (1400, "OpenClipboard", "Nieprawidłowy uchwyt okna.") – foosion

+0

Czy widzisz stronę z dokumentacją dotyczącą kodów formatu? 8 to 'BITMAPINFO', a 7 to' BITMAPV5HEADER', z których oba zawierają dane bitmapowe. Może skończyć się potrzeba, aby dowiedzieć się więcej o tym, jak system Windows obsługuje obrazy, niż chcesz ... – bgporter

+0

Żadnego z kodów wymienionych w http://msdn.microsoft.com/en-us/library/ff729168(v=VS.85) .aspx przejdź do 49353. Następna wartość to 8, która jest strukturą BITMAPINFO, ale nie mam pojęcia, co z nią zrobić. – foosion

4

Musisz przekazać parametr do GetClipboardData określając format danych, których szukasz. Możesz użyć formatu EnumClipboardFormats, aby zobaczyć formaty, które są dostępne - kiedy kopiuję coś w Eksploratorze mam do dyspozycji 15 formatów.

Edytuj 2: Oto kod, aby uzyskać nazwę pliku po skopiowaniu pliku w Eksploratorze. Odpowiedź będzie zupełnie inna, jeśli skopiujesz obraz z poziomu programu, na przykład przeglądarki.

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

Edit 3: Z uwag to jasne masz rzeczywisty obraz w schowku, a nie nazwę pliku pliku obrazu. Pan stwierdził, że nie można używać PIL, więc:

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

W tym momencie masz ciąg w Pythonie (2) lub bajtów (w Pythonie 3), który zawiera dane obrazu. Jedynym formatem, który możesz zapisać, jest .BMP, a będziesz musiał zdekodować BITMAPINFOHEADER, aby uzyskać parametry dla BITMAPFILEHEADER, które należy zapisać na wierzchu pliku.

+0

Mogę samodzielnie utworzyć nazwę pliku. Czy przechodzę przez EnumClipboardFormats() zaczynając od 0? Co mam zrobić z wynikami? – foosion

+0

@foosion, czy możesz dokładnie opisać zawartość schowka? Czy wykonałeś kopię na obrazie wyświetlanym w programie lub na nazwie pliku w Eksploratorze? –

+0

Moje bieżące testy polegają na skopiowaniu obrazu ze strony w przeglądarce internetowej iz programu do malowania. Zobacz także mój komentarz do bgporter – foosion

2

Korzystanie PythonMagick (binaries):

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

To wygląda obiecująco, a nawet obsługuje zarówno klip-> plik i plik-> klip. – foosion

Powiązane problemy