2011-12-15 5 views
2

저는 Ubuntu 10.04에서 Python을 사용하여 화면의 일부분 만 스크린 샷으로 만들려고합니다.GTK를 사용하는 화면 하위 영역의 스크린 샷

여기 내 코드입니다 (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 

아무것도. 전체 드로어 블을 픽셀 버퍼로 캡처 한 다음 필요한 픽셀로 변환하기 전에 각 픽셀 버퍼를 자릅니다.

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 enter image description here 2 enter image description here 3 enter image description here

가 주류이며 : enter image description here

이제 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 
+0

매우 기분이 좋지 않지만 [셔터] (http://shutter-project.org/)를 사용하고 싶을 수도 있습니다. : shutter -s = X, Y, WIDTH, HEIGHT -e' – jcollado

답변

4

나는 그것이 메모리에 저장 될 때 get_pixels 당신에게 데이터를 반환하기 때문에 그 생각합니다. 여기서 누락 된 부분은 메모리 정렬 제약 때문에 성능상의 이유로 한 줄에 끝에 패딩이있을 수 있다는 것입니다.

GdkPixbuf structure을 참조하십시오. 흥미로운 정보는 행의 시작과 다음 행의 시작 사이의 바이트 수인 rowstride입니다. 행의 데이터 바이트 수 + 패딩 바이트 수와 같습니다.

주의하시기 바랍니다. 마지막 줄에는 패딩이 없습니다.

+1

바른 길에. 버퍼는 윈도우의 전체 크기 였지만 필요한 소구역과 같은 크기 인 것처럼 처리했습니다. 하위 영역 밖에서는 아무 것도 필요로하지 않기 때문에 버퍼의 크기를 부분 영역의 크기로 줄임으로써 문제를 해결했습니다. – misha