Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastest way to take a screenshot with python on windows

What's the fastest way to take a screenshot on windows? PIL.ImageGrab is rather slow.. it takes between 4-5 seconds to take 30 screenshots of the same small window. Taking screenshots of the whole desktop is even slower.

like image 520
Claudiu Avatar asked Aug 27 '10 16:08

Claudiu


People also ask

How do I screenshot faster in Python?

Get the numpy representation of screenshot import mss import numpy as np with mss. mss() as sct: monitor = {"top": 160, "left": 160, "width": 160, "height": 135} img_array = np. array(sct. grab(monitor)) # Do whatever you want...

How do I take a screenshot instantly in Windows?

Alt + Print Screen To take a quick screenshot of the active window, use the keyboard shortcut Alt + PrtScn. This will snap your currently active window and copy the screenshot to the clipboard. You'll need to open the shot in an image editor to save it.

Can we take screenshot using Python?

PIL is one of the most famous Python libraries for working with images and is widely used for image processing. It is not a surprise to expect the screenshot functionality included in it as well. Similarly to the pyautogui solution, PIL allows to take a screenshot using Python in three lines of code as well.


2 Answers

You could use win32 APIs directly .

  1. First give the focus to the App that you want to take screenshot of. link text

  2. Win32 API can help with the screenshot:

import win32gui
import win32ui
import win32con

w = 1920 # set this
h = 1080 # set this
bmpfilenamename = "out.bmp" #set this

hwnd = win32gui.FindWindow(None, windowname)
wDC = win32gui.GetWindowDC(hwnd)
dcObj=win32ui.CreateDCFromHandle(wDC)
cDC=dcObj.CreateCompatibleDC()
dataBitMap = win32ui.CreateBitmap()
dataBitMap.CreateCompatibleBitmap(dcObj, w, h)
cDC.SelectObject(dataBitMap)
cDC.BitBlt((0,0),(w, h) , dcObj, (0,0), win32con.SRCCOPY)
dataBitMap.SaveBitmapFile(cDC, bmpfilenamename)

# Free Resources
dcObj.DeleteDC()
cDC.DeleteDC()
win32gui.ReleaseDC(hwnd, wDC)
win32gui.DeleteObject(dataBitMap.GetHandle())
like image 118
pyfunc Avatar answered Sep 27 '22 17:09

pyfunc


Just found out how to do it with gtk. Seems fastest by far:

def image_grab_gtk(window):
    left, top, right, bot = get_rect(window)
    w = right - left
    h = bot - top

    s = gtk.gdk.Pixbuf(
        gtk.gdk.COLORSPACE_RGB, False, 8, w, h)

    s.get_from_drawable(
        gtk.gdk.get_default_root_window(),
        gtk.gdk.colormap_get_system(),
        left, top, 0, 0, w, h )

    final = Image.frombuffer(
        "RGB",
        (w, h),
        s.get_pixels(),
        "raw",
        "RGB",
        s.get_rowstride(), 1)
    return final

Without converting to a PIL Image, it's 8x faster than PIL on my test case. With converting, it's still ~2.7x faster.

like image 34
Claudiu Avatar answered Sep 27 '22 16:09

Claudiu