我在剪貼板中有截圖。如何將圖像保存到沒有PIL的剪貼板中?
我已經使用win32clipboard.GetClipboardData(win32con.CF_DIB)
來獲取一個字符串,並將該字符串寫入一個.bmp文件,但它不能被圖片查看器打開。
因此,沒有PIL(和其他圖像第三部分庫),如何將剪貼板中的圖像寫入本地?
我在剪貼板中有截圖。如何將圖像保存到沒有PIL的剪貼板中?
我已經使用win32clipboard.GetClipboardData(win32con.CF_DIB)
來獲取一個字符串,並將該字符串寫入一個.bmp文件,但它不能被圖片查看器打開。
因此,沒有PIL(和其他圖像第三部分庫),如何將剪貼板中的圖像寫入本地?
您的簡單方法的主要問題是寫入文件的字符串缺少.bmp
文件標頭,這是一個BITMAPFILEHEADER
結構。
爲了創建文件頭,必須解碼由GetClipboardData()
調用返回的字符串中的至少一些信息。對於CF_DIB
剪貼板格式,字符串中數據的第一部分將是BITMAPINFOHEADER
。
這個頭結構是一個非常普遍的,因爲有許多不同類型的DIB,每個組件和壓縮類型都有不同的風格。幸運的是,用於截圖的那個非常簡單 - 未壓縮的RGBA像素。
這一事實使事情變得容易得多,因爲另有決定把在BITMAPFILEHEADER
的bfOffBits
字段中的值會被這樣的事實,在大多數其它情況下也就是跟隨BITMAPINFOHEADER
和開始的可變大小的色表很複雜像素陣列。
下面是處理這種情況的示例代碼(僅):
import ctypes
from ctypes.wintypes import *
import win32clipboard
from win32con import *
import sys
class BITMAPFILEHEADER(ctypes.Structure):
_pack_ = 1 # structure field byte alignment
_fields_ = [
('bfType', WORD), # file type ("BM")
('bfSize', DWORD), # file size in bytes
('bfReserved1', WORD), # must be zero
('bfReserved2', WORD), # must be zero
('bfOffBits', DWORD), # byte offset to the pixel array
]
SIZEOF_BITMAPFILEHEADER = ctypes.sizeof(BITMAPFILEHEADER)
class BITMAPINFOHEADER(ctypes.Structure):
_pack_ = 1 # structure field byte alignment
_fields_ = [
('biSize', DWORD),
('biWidth', LONG),
('biHeight', LONG),
('biPLanes', WORD),
('biBitCount', WORD),
('biCompression', DWORD),
('biSizeImage', DWORD),
('biXPelsPerMeter', LONG),
('biYPelsPerMeter', LONG),
('biClrUsed', DWORD),
('biClrImportant', DWORD)
]
SIZEOF_BITMAPINFOHEADER = ctypes.sizeof(BITMAPINFOHEADER)
win32clipboard.OpenClipboard()
try:
if win32clipboard.IsClipboardFormatAvailable(win32clipboard.CF_DIB):
data = win32clipboard.GetClipboardData(win32clipboard.CF_DIB)
else:
print('clipboard does not contain an image in DIB format')
sys.exit(1)
finally:
win32clipboard.CloseClipboard()
bmih = BITMAPINFOHEADER()
ctypes.memmove(ctypes.pointer(bmih), data, SIZEOF_BITMAPINFOHEADER)
if bmih.biCompression != BI_BITFIELDS: # RGBA?
print('insupported compression type {}'.format(bmih.biCompression))
sys.exit(1)
bmfh = BITMAPFILEHEADER()
ctypes.memset(ctypes.pointer(bmfh), 0, SIZEOF_BITMAPFILEHEADER) # zero structure
bmfh.bfType = ord('B') | (ord('M') << 8)
bmfh.bfSize = SIZEOF_BITMAPFILEHEADER + len(data) # file size
SIZEOF_COLORTABLE = 0
bmfh.bfOffBits = SIZEOF_BITMAPFILEHEADER + SIZEOF_BITMAPINFOHEADER + SIZEOF_COLORTABLE
bmp_filename = 'clipboard.bmp'
with open(bmp_filename, 'wb') as bmp_file:
bmp_file.write(bmfh)
bmp_file.write(data)
print('file "{}" created from clipboard image'.format(bmp_filename))
你有任何*碼*,做了嗎?如果是這樣,不會**包括它**幫助我們回答你? – Tersosauros
**「將剪貼板中的圖像寫入本地」是什麼意思? – martineau
@martineau這意味着我在剪貼板中有截圖,我想將它保存在文件中。 – Kingname