def screen(self):
"""PIL Image of current window screen. (the window must be on the top)
reference: https://msdn.microsoft.com/en-us/library/dd183402(v=vs.85).aspx"""
# opengl windows cannot get from it's hwnd, so we use the screen
hwnd = win32gui.GetDesktopWindow()
# get window size and offset
left, top, right, bottom = self.rect
width, height = right-left, bottom-top
# the device context of the window
hdcwin = win32gui.GetWindowDC(hwnd)
# make a temporary dc
hdcmem = win32gui.CreateCompatibleDC(hdcwin)
# make a temporary bitmap in memory, this is a PyHANDLE object
hbmp = win32gui.CreateCompatibleBitmap(hdcwin, width, height)
# select bitmap for temporary dc
win32gui.SelectObject(hdcmem, hbmp)
# copy bits to temporary dc
win32gui.BitBlt(hdcmem, 0, 0, width, height,
hdcwin, left, top, win32con.SRCCOPY)
# check the bitmap object infomation
bmp = win32gui.GetObject(hbmp)
bi = BITMAPINFOHEADER()
bi.biSize = ctypes.sizeof(BITMAPINFOHEADER)
bi.biWidth = bmp.bmWidth
bi.biHeight = bmp.bmHeight
bi.biPlanes = bmp.bmPlanes
bi.biBitCount = bmp.bmBitsPixel
bi.biCompression = 0 # BI_RGB
bi.biSizeImage = 0
bi.biXPelsPerMeter = 0
bi.biYPelsPerMeter = 0
bi.biClrUsed = 0
bi.biClrImportant = 0
# calculate total size for bits
pixel = bmp.bmBitsPixel
size = ((bmp.bmWidth * pixel + pixel - 1)/pixel) * 4 * bmp.bmHeight
buf = (ctypes.c_char * size)()
# read bits into buffer
windll.gdi32.GetDIBits(hdcmem, hbmp.handle, 0, bmp.bmHeight, buf, ctypes.byref(bi), win32con.DIB_RGB_COLORS)
# make a PIL Image
img = Image.frombuffer('RGB', (bmp.bmWidth, bmp.bmHeight), buf, 'raw', 'BGRX', 0, 1)
img = img.transpose(Image.FLIP_TOP_BOTTOM)
# cleanup
win32gui.DeleteObject(hbmp)
win32gui.DeleteObject(hdcmem)
win32gui.ReleaseDC(hwnd, hdcwin)
return img
评论列表
文章目录