FAQ Index - Search - Recent Changes - Everything - Add entry

<< Previous Entry | FAQ Entry 23.39 | Next Entry >>

23.39. How do I acquire a screenshot of the active window?

I do not think this works in Windows since _NET_WM_* hints might not be supported there.

Use the GDK Pixbuf API. Although it will only output to PNG and JPEG, the latter having an optional quality option passed as a dict with a quality value string of 0-100 to the gdk.Pixbuf save() method.

 # Calculate the size of the whole screen
 screenw = gtk.gdk.screen_width()
 screenh = gtk.gdk.screen_height()

 # Get the root and active window
 root = gtk.gdk.screen_get_default()

 if root.supports_net_wm_hint("_NET_ACTIVE_WINDOW") and root.supports_net_wm_hint("_NET_WM_WINDOW_TYPE"):
        active = root.get_active_window()
        # You definately do not want to take a screenshot of the whole desktop, see entry 23.36 for that
        # Returns something like ('ATOM', 32, ['_NET_WM_WINDOW_TYPE_DESKTOP'])
        if active.property_get("_NET_WM_WINDOW_TYPE")[-1][0] == '_NET_WM_WINDOW_TYPE_DESKTOP':
         return False

        # Calculate the size of the wm decorations
        relativex, relativey, winw, winh, d = active.get_geometry() 
        w = winw + (relativex*2)
        h = winh + (relativey+relativex)

        # Calculate the position of where the wm decorations start (not the window itself)
        screenposx, screenposy = active.get_root_origin()
 else:
        return False

 screenshot = gtk.gdk.Pixbuf.get_from_drawable(gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, w, h),
            gtk.gdk.get_default_root_window(),
            gtk.gdk.colormap_get_system(),
            screenposx, screenposy, 0, 0, w, h)

 # Either "png" or "jpeg" (case matters)
 format = "jpeg"

 # Pixbuf's have a save method 
 # Note that png doesnt support the quality argument. 
 screenshot.save("screenshot." + format, format,  {"quality": "20"})
Warning: if you plan on running this code on a loop, or many times throughout the program, you might want to add the following code to avoid a big memory leak (considering the size of a bitmap of those proportions), as per a bug detailed here: [www.async.com.br]

 del screenshot
 gc.collect()

PyGTK FAQ Wizard | PyGTK Homepage | Feedback to faq at pygtk.org