2008-09-16 55 views
69

我想通過一個python腳本截圖並不顯眼地保存它。通過python腳本截圖。 [Linux]

我只對Linux解決方案感興趣,應該支持任何基於X的環境。

+0

不能使用[scrot(HTTP任何理由://linux.die .NET /人/ 1/scrot)? – Mark 2009-04-20 10:46:48

+0

我很想查看下面的建議方法的性能。 – JDong 2014-07-01 17:01:57

+0

@Mark - 無效鏈接。 – ArtOfWarfare 2015-08-01 13:18:56

回答

59

此工程無需使用scrot或ImageMagick。

import gtk.gdk 

w = gtk.gdk.get_default_root_window() 
sz = w.get_size() 
print "The size of the window is %d x %d" % sz 
pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,False,8,sz[0],sz[1]) 
pb = pb.get_from_drawable(w,w.get_colormap(),0,0,0,0,sz[0],sz[1]) 
if (pb != None): 
    pb.save("screenshot.png","png") 
    print "Screenshot saved to screenshot.png." 
else: 
    print "Unable to get the screenshot." 

使用wxPythonhttp://ubuntuforums.org/showpost.php?p=2681009&postcount=5

3

找到了一個簡短的搜索gtkShots看起來像它可能會幫助你,因爲它是一個GPLed python屏幕截圖程序,所以應該有你需要的東西。

7
import ImageGrab 
img = ImageGrab.grab() 
img.save('test.jpg','JPEG') 

這需要Python圖像庫

+18

只適用於Windows:http://www.pythonware.com/library/ pil/handbook/imagegrab.htm – bernie 2009-04-04 19:52:12

18

這一個適用於X11,也許在Windows太(某人,請檢查)。 Needs PyQt4

import sys 
from PyQt4.QtGui import QPixmap, QApplication 
app = QApplication(sys.argv) 
QPixmap.grabWindow(QApplication.desktop().winId()).save('test.png', 'png') 
+2

請注意PyQt的許可,它比Python和Qt更具限制性。 http://www.riverbankcomputing.co.uk/software/pyqt/license – user120242 2009-08-13 05:09:19

+0

用戶kmilin(以下)報告說,這在Windows上工作 – 2009-12-03 15:07:29

+0

這是唯一的解決方案,可以在我的Linux安裝上「開箱即用」 。我不知道爲什麼,但我到處都有PyQt4,而缺乏PyWX,PyGtk,ImageGrab。 - 謝謝 :)。 – 2012-02-03 19:17:53

8

跨平臺解決方案,借:

import wx 
wx.App() # Need to create an App instance before doing anything 
screen = wx.ScreenDC() 
size = screen.GetSize() 
bmp = wx.EmptyBitmap(size[0], size[1]) 
mem = wx.MemoryDC(bmp) 
mem.Blit(0, 0, size[0], size[1], screen, 0, 0) 
del mem # Release bitmap 
bmp.SaveFile('screenshot.png', wx.BITMAP_TYPE_PNG) 
41

編譯所有的答案中的一類。 輸出PIL圖像。

#!/usr/bin/env python 
# encoding: utf-8 
""" 
screengrab.py 

Created by Alex Snet on 2011-10-10. 
Copyright (c) 2011 CodeTeam. All rights reserved. 
""" 

import sys 
import os 

import Image 


class screengrab: 
    def __init__(self): 
     try: 
      import gtk 
     except ImportError: 
      pass 
     else: 
      self.screen = self.getScreenByGtk 

     try: 
      import PyQt4 
     except ImportError: 
      pass 
     else: 
      self.screen = self.getScreenByQt 

     try: 
      import wx 
     except ImportError: 
      pass 
     else: 
      self.screen = self.getScreenByWx 

     try: 
      import ImageGrab 
     except ImportError: 
      pass 
     else: 
      self.screen = self.getScreenByPIL 


    def getScreenByGtk(self): 
     import gtk.gdk  
     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]) 
     pb = pb.get_from_drawable(w,w.get_colormap(),0,0,0,0,sz[0],sz[1]) 
     if pb is None: 
      return False 
     else: 
      width,height = pb.get_width(),pb.get_height() 
      return Image.fromstring("RGB",(width,height),pb.get_pixels()) 

    def getScreenByQt(self): 
     from PyQt4.QtGui import QPixmap, QApplication 
     from PyQt4.Qt import QBuffer, QIODevice 
     import StringIO 
     app = QApplication(sys.argv) 
     buffer = QBuffer() 
     buffer.open(QIODevice.ReadWrite) 
     QPixmap.grabWindow(QApplication.desktop().winId()).save(buffer, 'png') 
     strio = StringIO.StringIO() 
     strio.write(buffer.data()) 
     buffer.close() 
     del app 
     strio.seek(0) 
     return Image.open(strio) 

    def getScreenByPIL(self): 
     import ImageGrab 
     img = ImageGrab.grab() 
     return img 

    def getScreenByWx(self): 
     import wx 
     wx.App() # Need to create an App instance before doing anything 
     screen = wx.ScreenDC() 
     size = screen.GetSize() 
     bmp = wx.EmptyBitmap(size[0], size[1]) 
     mem = wx.MemoryDC(bmp) 
     mem.Blit(0, 0, size[0], size[1], screen, 0, 0) 
     del mem # Release bitmap 
     #bmp.SaveFile('screenshot.png', wx.BITMAP_TYPE_PNG) 
     myWxImage = wx.ImageFromBitmap(myBitmap) 
     PilImage = Image.new('RGB', (myWxImage.GetWidth(), myWxImage.GetHeight())) 
     PilImage.fromstring(myWxImage.GetData()) 
     return PilImage 

if __name__ == '__main__': 
    s = screengrab() 
    screen = s.screen() 
    screen.show() 
12

我有scrot,ImageMagick的,PyQt的,WX和PyGTK的一個包裝項目(pyscreenshot)。 如果你有其中一個,你可以使用它。 本討論包含所有解決方案。

安裝:

easy_install pyscreenshot 

例子:

import pyscreenshot as ImageGrab 

# fullscreen 
im=ImageGrab.grab() 
im.show() 

# part of the screen 
im=ImageGrab.grab(bbox=(10,10,500,500)) 
im.show() 

# to file 
ImageGrab.grab_to_file('im.png') 
29

只是爲了完整性: Xlib的 - 但捕捉整個屏幕時,它的有些慢:

from Xlib import display, X 
import Image #PIL 

W,H = 200,200 
dsp = display.Display() 
root = dsp.screen().root 
raw = root.get_image(0, 0, W,H, X.ZPixmap, 0xffffffff) 
image = Image.fromstring("RGB", (W, H), raw.data, "raw", "BGRX") 
image.show() 

人們可以嘗試在PyXlib的瓶頸文件中放入一些類型,然後使用Cython進行編譯。這可能會提高速度。


編輯: 我們可以寫在C函數的核心,然後從ctypes的Python中使用它,這裏是我砍死在一起:

#include <stdio.h> 
#include <X11/X.h> 
#include <X11/Xlib.h> 
//Compile hint: gcc -shared -O3 -lX11 -fPIC -Wl,-soname,prtscn -o prtscn.so prtscn.c 

void getScreen(const int, const int, const int, const int, unsigned char *); 
void getScreen(const int xx,const int yy,const int W, const int H, /*out*/ unsigned char * data) 
{ 
    Display *display = XOpenDisplay(NULL); 
    Window root = DefaultRootWindow(display); 

    XImage *image = XGetImage(display,root, xx,yy, W,H, AllPlanes, ZPixmap); 

    unsigned long red_mask = image->red_mask; 
    unsigned long green_mask = image->green_mask; 
    unsigned long blue_mask = image->blue_mask; 
    int x, y; 
    int ii = 0; 
    for (y = 0; y < H; y++) { 
     for (x = 0; x < W; x++) { 
     unsigned long pixel = XGetPixel(image,x,y); 
     unsigned char blue = (pixel & blue_mask); 
     unsigned char green = (pixel & green_mask) >> 8; 
     unsigned char red = (pixel & red_mask) >> 16; 

     data[ii + 2] = blue; 
     data[ii + 1] = green; 
     data[ii + 0] = red; 
     ii += 3; 
     } 
    } 
    XDestroyImage(image); 
    XDestroyWindow(display, root); 
    XCloseDisplay(display); 
} 

然後蟒蛇-file:

import ctypes 
import os 
from PIL import Image 

LibName = 'prtscn.so' 
AbsLibPath = os.path.dirname(os.path.abspath(__file__)) + os.path.sep + LibName 
grab = ctypes.CDLL(AbsLibPath) 

def grab_screen(x1,y1,x2,y2): 
    w, h = x2-x1, y2-y1 
    size = w * h 
    objlength = size * 3 

    grab.getScreen.argtypes = [] 
    result = (ctypes.c_ubyte*objlength)() 

    grab.getScreen(x1,y1, w, h, result) 
    return Image.frombuffer('RGB', (w, h), result, 'raw', 'RGB', 0, 1) 

if __name__ == '__main__': 
    im = grab_screen(0,0,1440,900) 
    im.show() 
-3

試試:

#!/usr/bin/python 

import gtk.gdk 
import time 
import random 
import socket 
import fcntl 
import struct 
import getpass 
import os 
import paramiko  

while 1: 
    # generate a random time between 120 and 300 sec 
    random_time = random.randrange(20,25) 
    # wait between 120 and 300 seconds (or between 2 and 5 minutes) 

    print "Next picture in: %.2f minutes" % (float(random_time)/60) 

    time.sleep(random_time) 
    w = gtk.gdk.get_default_root_window() 
    sz = w.get_size() 
    print "The size of the window is %d x %d" % sz 
    pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,False,8,sz[0],sz[1]) 
    pb = pb.get_from_drawable(w,w.get_colormap(),0,0,0,0,sz[0],sz[1]) 
    ts = time.asctime(time.localtime(time.time())) 
    date = time.strftime("%d-%m-%Y") 
    timer = time.strftime("%I:%M:%S%p") 
    filename = timer 
    filename += ".png" 

    if (pb != None): 
     username = getpass.getuser() #Get username 
     newpath = r'screenshots/'+username+'/'+date #screenshot save path 
     if not os.path.exists(newpath): os.makedirs(newpath) 
     saveas = os.path.join(newpath,filename) 
     print saveas 
     pb.save(saveas,"png") 
    else: 
     print "Unable to get the screenshot." 
2

有一個Python包,這Autopy

位圖模塊,篩選抓(bitmap.capture_screen) 這是multiplateform(Windows,Linux和OSX)。

0

這是一個古老的問題。我想用新工具回答它。

適用於python 3(應該使用python 2,但我沒有測試過)和PyQt5。

最小工作示例。將它複製到python shell並獲得結果。

from PyQt5.QtWidgets import QApplication 
app = QApplication([]) 
screen = app.primaryScreen() 
screenshot = screen.grabWindow(QApplication.desktop().winId()) 
screenshot.save('/tmp/screenshot.png') 
2

有點晚了,但沒關係容易的是

import autopy 
import time 
time.sleep(2) 
b = autopy.bitmap.capture_screen() 
b.save("C:/Users/mak/Desktop/m.png") 
1

我不能把屏幕截圖的Linux與pyscreenshot或scrot因爲pyscreenshot輸出只是一個黑屏png圖像文件。

但感謝上帝,還有另一種非常簡單的方式在Linux中進行截圖,而無需安裝任何東西。只要把下面的代碼在你的目錄,並與python demo.py

import os 
os.system("gnome-screenshot --file=this_directory.png") 

運行也有許多可用的選項gnome-screenshot --help

Application Options: 
    -c, --clipboard    Send the grab directly to the clipboard 
    -w, --window     Grab a window instead of the entire screen 
    -a, --area      Grab an area of the screen instead of the entire screen 
    -b, --include-border   Include the window border with the screenshot 
    -B, --remove-border   Remove the window border from the screenshot 
    -p, --include-pointer   Include the pointer with the screenshot 
    -d, --delay=seconds   Take screenshot after specified delay [in seconds] 
    -e, --border-effect=effect  Effect to add to the border (shadow, border, vintage or none) 
    -i, --interactive    Interactively set options 
    -f, --file=filename   Save screenshot directly to this file 
    --version      Print version information and exit 
    --display=DISPLAY    X display to use