2011-08-12 60 views
9

Tôi có hình ảnh (jpg, png, v.v.) trong khay nhớ tạm của cửa sổ. Tôi muốn lưu nó vào một tập tin. win32clipboard dường như là câu trả lời, nhưng mỗi ví dụ tôi có thể tìm thấy các giao dịch với văn bản.Làm cách nào để đọc jpg hoặc png từ khay nhớ tạm của windows trong python và ngược lại?

sao chép một hình ảnh vào clipboard, sau đó

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

không thành công với

TypeError: Specified clipboard format is not available 

Tôi cũng muốn làm điều ngược lại - đưa ra một tập tin ảnh, hãy viết nó vào clipboard.

+1

Nếu bạn đang mở để sử dụng các mô-đun wx bạn có thể làm: http://stackoverflow.com/questions/2629907/wx-read-image-from-clipboard – blcArmadillo

+0

Tôi đang cố gắng viết một tiện ích dòng lệnh đơn giản và hiện không sử dụng wx, vì vậy tôi không muốn đến đó. – foosion

Trả lời

16

tôi sẽ chỉ cần sử dụng Pillow:

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

Tôi đã chỉ nhìn vào đó, nhưng tôi cần cả hai python 2,7 và 3,2 và PIL dường như không có sẵn cho 3.2 – foosion

+0

@foosion: Tôi nghĩ rằng có một nhị phân biên dịch trước cho python 3.2 ở đây: http: //www.lfd .uci.edu/~ gohlke/pythonlibs/ – Gerrat

+0

Điều này thật đơn giản với 2.7. Tôi đã hy vọng rằng thêm một vài dòng vào phiên bản win32clipboard sẽ làm việc như thế này. – foosion

4

Hàm win32clipboard.GetClipboardData() có tham số. Tham số mặc định chỉ định rằng bạn muốn nội dung của khay nhớ tạm làm văn bản. Bạn cần chuyển giá trị chỉ định định dạng dữ liệu bạn muốn clipboard cung cấp cho bạn.

Định dạng dữ liệu khay nhớ tạm tiêu chuẩn được ghi thành tài liệu here.

CŨNG:

Xem here cho các tài liệu trên EnumClipboardFormats() - về cơ bản, bạn cần có mã như (chưa được kiểm tra) này để có được những định dạng mà có sẵn hiện trên clipboard:

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

Tôi chỉ thử liệt kê các định dạng và có 49353, 0, 8, 0, 0, 0, 0, 17, 0. Tôi có sử dụng 49353 không? win32clipboard.OpenClipboard (49353) dẫn đến lỗi: (1400, 'OpenClipboard', 'Xử lý cửa sổ không hợp lệ.') – foosion

+0

Bạn có thấy trang có tài liệu về mã định dạng không? 8 là 'BITMAPINFO' và 7 là' BITMAPV5HEADER', cả hai đều bao gồm dữ liệu bitmap. Bạn có thể cần phải tìm hiểu thêm về cách Windows xử lý hình ảnh hơn bạn muốn ... – bgporter

+0

Không có mã nào được liệt kê trong http://msdn.microsoft.com/en-us/library/ff729168(v=VS.85) .aspx lên tới 49353. Giá trị tiếp theo là 8, là cấu trúc BITMAPINFO, nhưng tôi không rõ ràng về việc phải làm gì với nó – foosion

4

Bạn cần chuyển thông số sang số GetClipboardData chỉ định định dạng dữ liệu bạn đang tìm kiếm. Bạn có thể sử dụng EnumClipboardFormats để xem các định dạng có sẵn - khi tôi sao chép nội dung nào đó trong Explorer, có 15 định dạng có sẵn cho tôi.

Chỉnh sửa 2: Đây là mã để lấy tên tệp sau khi bạn đã sao chép tệp trong Explorer. Câu trả lời sẽ hoàn toàn khác nếu bạn đã sao chép một hình ảnh từ bên trong một chương trình, ví dụ như một trình duyệt.

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

Sửa 3: Từ các ý kiến ​​thì rõ ràng bạn có một hình ảnh thực tế trong clipboard, không phải là tên tập tin của một tập tin hình ảnh. Bạn đã tuyên bố rằng bạn không thể sử dụng PIL, vì vậy:

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

Tại thời điểm này bạn có một chuỗi (bằng Python 2) hoặc byte (trong Python 3) có chứa dữ liệu hình ảnh. Định dạng duy nhất bạn có thể lưu là .BMP và bạn sẽ phải giải mã BITMAPINFOHEADER để nhận thông số cho số BITMAPFILEHEADER cần được ghi vào mặt trước của tệp.

+0

Tôi có thể tự tạo tên tệp. Tôi có chạy qua EnumClipboardFormats() bắt đầu bằng 0 không? Tôi phải làm gì với kết quả? – foosion

+0

@foosion, bạn có thể xây dựng chính xác những gì trong khay nhớ tạm không? Bạn đã làm một bản sao trên một hình ảnh được hiển thị trong một chương trình, hoặc trên một tên tập tin trong Explorer? –

+0

Các thử nghiệm hiện tại của tôi là sao chép một hình ảnh từ một trang trong trình duyệt web và từ một chương trình vẽ. Ngoài ra, xin vui lòng xem bình luận của tôi để bgporter – foosion

2

Sử dụng PythonMagick (binaries):

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

Điều đó có vẻ đầy hứa hẹn và thậm chí hỗ trợ cả clip-> tệp và tệp-> clip. – foosion

Các vấn đề liên quan