Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Screenshot of background/inactive window

Tags:

python

I am attempting to take fast screenshots ready for processing with PIL/Numpy (~0.01s per screenshot) with Python 3.6. Ideally the window would not need to be in the foreground, i.e. even when another window is covering it, the screenshot is still successful.

So far I've modified the code for python 3 from this question: Python Screenshot of inactive window PrintWindow + win32gui

However, all it gets is black images.

import win32gui
import win32ui
from ctypes import windll
from PIL import Image

hwnd = win32gui.FindWindow(None, 'Calculator')

# Get window bounds
left, top, right, bot = win32gui.GetWindowRect(hwnd)
w = right - left
h = bot - top

hwndDC = win32gui.GetWindowDC(hwnd)
mfcDC = win32ui.CreateDCFromHandle(hwndDC)
saveDC = mfcDC.CreateCompatibleDC()

saveBitMap = win32ui.CreateBitmap()
saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)

saveDC.SelectObject(saveBitMap)

result = windll.user32.PrintWindow(hwnd, saveDC.GetSafeHdc(), 1)
print(result)

bmp_info = saveBitMap.GetInfo()
bmp_str = saveBitMap.GetBitmapBits(True)
print(bmp_str)

im = Image.frombuffer(
    'RGB',
    (bmp_info['bmWidth'], bmp_info['bmHeight']),
    bmp_str, 'raw', 'BGRX', 0, 1)

win32gui.DeleteObject(saveBitMap.GetHandle())
saveDC.DeleteDC()
mfcDC.DeleteDC()
win32gui.ReleaseDC(hwnd, hwndDC)

if result == 1:
    im.save("screenshot.png")
like image 328
kainev Avatar asked Nov 30 '18 05:11

kainev


People also ask

How to take a screenshot in Python?

Begin with importing the pyautogui library: Then call the .screenshot () method, which will return and Image object. And simply save it using any filename that works for you: And you should get a .png file in the same directory as your Python code. Below is an example of what my screenshot looks like:

How to keep Tkinter window away from taking screenshots?

In order to keep the Tkinter window away from taking screenshots as well as in the image, we can use withdraw () function to withdraw the image. Running the above code will display a window that contains a button and a Label text. When we click the button, it will take a screenshot of the window and save it in a local directory.

How to take a screenshot in pyautogui?

The PyAutoGUI module provides a screenshot () method to take a screenshot. When we run the above code, the screenshot will be saved at the specified location. In the above example, we have not mentioned the time. Suppose we want to take a screenshot of some other window, so what can we do?

How to take a screenshot in the foreground of a window?

With the library pywin32, you can. When you get the identifier of the window (for example by the name) you can set it to the foreground with the function SetForegroundWindow. And after, take a screenshot with PIL (pillow) when you get position and size.


1 Answers

This code worked for me with applications in background, not minimized.

import win32gui
import win32ui

def background_screenshot(hwnd, width, height):
    wDC = win32gui.GetWindowDC(hwnd)
    dcObj=win32ui.CreateDCFromHandle(wDC)
    cDC=dcObj.CreateCompatibleDC()
    dataBitMap = win32ui.CreateBitmap()
    dataBitMap.CreateCompatibleBitmap(dcObj, width, height)
    cDC.SelectObject(dataBitMap)
    cDC.BitBlt((0,0),(width, height) , dcObj, (0,0), win32con.SRCCOPY)
    dataBitMap.SaveBitmapFile(cDC, 'screenshot.bmp')
    dcObj.DeleteDC()
    cDC.DeleteDC()
    win32gui.ReleaseDC(hwnd, wDC)
    win32gui.DeleteObject(dataBitMap.GetHandle())

hwnd = win32gui.FindWindow(None, windowname)
background_screenshot(hwnd, 1280, 780)
like image 53
Alexandre Calil Avatar answered Oct 06 '22 06:10

Alexandre Calil