【问题标题】:Screenshot of screen subregion using GTK使用 GTK 的屏幕子区域的屏幕截图
【发布时间】:2011-12-23 02:00:19
【问题描述】:

我正在尝试在 Ubuntu 10.04 下使用 Python 仅截取屏幕的一部分。

这是我的代码(假设 IMAGE_GRAB 为 False):

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

这里没有什么花哨的。将整个可绘制对象捕获到像素缓冲区中,然后继续裁剪每个像素缓冲区,然后再将其转换为所需的 PIL 对象。

这是主线:

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()

生成的图像(除了第一个之外)都存在步幅问题:

1: 2: 3: 4:

现在,如果我在 PIL 中进行裁剪,一切正常:

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

我不想这样做,我想,因为从 GTK 到 PIL 的转换非常昂贵。这是一种浪费,因为我转换整个图像只是为了从中取出小的子区域。

谁能指出为什么 GTK 版本会出现跨步错误?

编辑

工作来源:

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

【问题讨论】:

  • 不是很pythonic,但你可能想使用shutter:shutter -s=X,Y,WIDTH,HEIGHT -e

标签: python gtk


【解决方案1】:

我认为这是因为 get_pixels 会返回存储在内存中的数据。您在这里缺少的是,出于性能原因(由于内存对齐限制),一行可能在其末尾有一些填充。

见GdkPixbuf structure:有趣的信息是rowstride,它是从一行开始到下一行开始之间的字节数。它等于一行中的数据字节数 + 填充字节数。

注意最后一行没有填充。

【讨论】:

  • 你让我走上了正轨。缓冲区是窗口的完整大小,但我处理它时好像它与所需的子区域大小相同。由于我不需要子区域之外的任何东西,因此我通过将缓冲区的大小减小到子区域的大小来解决问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-23
  • 1970-01-01
  • 2020-09-12
  • 2021-12-27
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
相关资源
最近更新 更多