感谢@Tarun Lalwani指出
this answer
,我终于有了一个暂时为我工作的代码。然而,在我看来,这是相当长的与许多不同的模块。也许它仍然可以简化。欢迎提出建议。
代码:
### get the content of a window and crop it
import win32gui, win32ui, win32clipboard
from io import BytesIO
from ctypes import windll
from PIL import Image
# user input
window_name = 'Gnuplot (window id : 0)'
margins = [8,63,8,31] # left, top, right, bottom
dpi = 96
hwnd = win32gui.FindWindow(None, window_name)
left, top, right, bottom = win32gui.GetWindowRect(hwnd)
width = right - left
height = bottom - top
crop_box = (margins[0],margins[1],width-margins[2],height-margins[3])
hwndDC = win32gui.GetWindowDC(hwnd)
mfcDC = win32ui.CreateDCFromHandle(hwndDC)
saveDC = mfcDC.CreateCompatibleDC()
saveBitMap = win32ui.CreateBitmap()
saveBitMap.CreateCompatibleBitmap(mfcDC, width, height)
saveDC.SelectObject(saveBitMap)
result = windll.user32.PrintWindow(hwnd, saveDC.GetSafeHdc(), 0)
bmpinfo = saveBitMap.GetInfo()
bmpstr = saveBitMap.GetBitmapBits(True)
im = Image.frombuffer( 'RGB', (bmpinfo['bmWidth'], bmpinfo['bmHeight']),
bmpstr, 'raw', 'BGRX', 0, 1).crop(crop_box)
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
output = BytesIO()
im.convert("RGB").save(output, "BMP", dpi=(dpi,dpi))
data = output.getvalue()[14:]
output.close()
win32clipboard.SetClipboardData(win32clipboard.CF_DIB, data)
win32clipboard.CloseClipboard()
win32gui.DeleteObject(saveBitMap.GetHandle())
saveDC.DeleteDC()
mfcDC.DeleteDC()
win32gui.ReleaseDC(hwnd, hwndDC)
print('"'+window_name+'"', "is now on the clipboard with", dpi, "dpi.")
### end of code