title: Screenshot of screen subregion using GTK
body: <p>I'm trying to take screenshots of only part of the screen using Python under Ubuntu 10.04.</p>
  
  <p>Here's my code (assume <code>IMAGE_GRAB</code> is False):</p>
  
  <pre><code>def screenshot_roi(regions):
      if IMAGE_GRAB:
          return map(ImageGrab.grab, regions)
      else:
          w = gtk.gdk.get_default_root_window()
          sz = w.get_size()
          pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,False,8,sz[0],sz[1])
          src = pb.get_from_drawable(w,w.get_colormap(),0,0,0,0,sz[0],sz[1])
          results = []
          for roi in regions:
              if not roi:
                  results.append(None)
                  continue
              x,y,width,height = roi
              dst = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,False,8,width,height)
              src.copy_area(x,y,width,height,dst,0,0)
              im = PIL.Image.fromstring("RGB", (width, height), dst.get_pixels())
              results.append(im)
          return results
  </code></pre>
  
  <p>Nothing that fancy here.  Captures the entire drawable into a pixel buffer, and then proceeds to crop each pixel buffer before converting it to the required PIL object.  </p>
  
  <p>This is the mainline:</p>
  
  <pre><code>def main():
      regions = [(845, 219, 248, 82), (1101, 243, 109, 59), 
                 (1213, 245, 66, 57), (1281, 245, 74, 58)]    
      images = screenshot_roi(regions)
      for i,roi in enumerate(images):
          if roi:
              roi.save('%d.png' % i)
  
  if __name__ == '__main__':
      main()
  </code></pre>
  
  <p>The resulting images (all except for the first one) have stride issues, though:</p>
  
  <p>1: <img src="https://i.stack.imgur.com/cz9PH.png" alt="enter image description here"> 
  2: <img src="https://i.stack.imgur.com/BgDJr.png" alt="enter image description here"> 
  3: <img src="https://i.stack.imgur.com/z91xp.png" alt="enter image description here"> 
  4: <img src="https://i.stack.imgur.com/qPGeP.png" alt="enter image description here"></p>
  
  <p>Now, if I do the cropping in PIL, everything works well:</p>
  
  <pre><code>def screenshot_roi(regions):
      if IMAGE_GRAB:
          return map(ImageGrab.grab, regions)
      else:
          w = gtk.gdk.get_default_root_window()
          sz = w.get_size()
          pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,False,8,sz[0],sz[1])
          src = pb.get_from_drawable(w,w.get_colormap(),0,0,0,0,sz[0],sz[1])
          entire_im = PIL.Image.fromstring("RGB", sz, src.get_pixels())
          results = []
          for roi in regions:
              if not roi:
                  results.append(None)
                  continue
              x,y,width,height = roi
              crop = entire_im.crop((x,y,x+width,y+height))
              crop.load()
              results.append(crop)
          return results
  </code></pre>
  
  <p>I don't want to do it this way, thought, because the conversion from GTK to PIL is quite expensive.  It's a waste because I'm converting the entire image just to get small sub-regions out of it.</p>
  
  <p>Can anyone suggest why the GTK version is having stride errors?</p>
  
  <p><em>EDIT</em></p>
  
  <p>Working source:</p>
  
  <pre><code>x,y,w,h = region
  win = gtk.gdk.get_default_root_window()
  pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,False,8,w,h)
  src = pb.get_from_drawable(win,win.get_colormap(),x,y,0,0,w,h)
  im = PIL.Image.frombuffer('RGB', (w,h), src.get_pixels(), 'raw', 
                  'RGB', src.get_rowstride(), 1)
  return im
  </code></pre>