Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I've used the following code examples to capture a screenshot:

https://stackoverflow.com/a/3260811 https://stackoverflow.com/a/24352388/5858697

When taking a screenshot of Firefox or chrome, they return a blank black image. Capturing a screenshot of notepad works fine. I've done some research on this and I think it's because they're gpu accelerated. Other screenshot libraries work but I need to have it so I can capture a screenshot of an application even if it's not currently visible.

Has anyone solved a similar problem or could someone point me in the right direction? Thank you.

Notepad is a Win32 program. Firefox and Chrome are not, you can't take screenshot like that. You have to take screenshot of the whole desktop, making sure the target window is on top, then crop the window area. Barmak Shemirani Dec 16, 2019 at 6:16

Based on the @Barmak's previous answer , I converted C + + code to python, and now it works.

import win32gui
import win32ui
import win32con
from ctypes import windll
from PIL import Image
import time
import ctypes
hwnd_target = 0x00480362 #Chrome handle be used for test 
left, top, right, bot = win32gui.GetWindowRect(hwnd_target)
w = right - left
h = bot - top
win32gui.SetForegroundWindow(hwnd_target)
time.sleep(1.0)
hdesktop = win32gui.GetDesktopWindow()
hwndDC = win32gui.GetWindowDC(hdesktop)
mfcDC  = win32ui.CreateDCFromHandle(hwndDC)
saveDC = mfcDC.CreateCompatibleDC()
saveBitMap = win32ui.CreateBitmap()
saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)
saveDC.SelectObject(saveBitMap)
result = saveDC.BitBlt((0, 0), (w, h), mfcDC, (left, top), win32con.SRCCOPY)
bmpinfo = saveBitMap.GetInfo()
bmpstr = saveBitMap.GetBitmapBits(True)
im = Image.frombuffer(
    'RGB',
    (bmpinfo['bmWidth'], bmpinfo['bmHeight']),
    bmpstr, 'raw', 'BGRX', 0, 1)
win32gui.DeleteObject(saveBitMap.GetHandle())
saveDC.DeleteDC()
mfcDC.DeleteDC()
win32gui.ReleaseDC(hdesktop, hwndDC)
if result == None:
    #PrintWindow Succeeded
    im.save("test.png")

Please note: Firefox uses Windowless Controls.

If you want to get the handle of Firefox, you may need UI Automation.

For a detailed explanation, please refer to @IInspectable's answer.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.