2008-09-16 15 views
69

मैं एक पायथन लिपि के माध्यम से एक स्क्रीनशॉट लेना चाहता हूं और इसे अनजाने में सहेजना चाहता हूं।एक पायथन लिपि के माध्यम से एक स्क्रीनशॉट लें। [लिनक्स]

मुझे केवल लिनक्स समाधान में दिलचस्पी है, और किसी भी एक्स आधारित वातावरण का समर्थन करना चाहिए।

+0

किसी भी कारण है कि आप उपयोग नहीं कर सकते [scrot] (http के लिए अपनी निर्देशिका में कोड के नीचे रख दिया और भी है कई विकल्प उपलब्ध है python demo.py

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

के साथ चलाने .net/आदमी/1/scrot)? – Mark

+0

मैं नीचे सुझाए गए तरीकों के प्रदर्शन की जांच करने के लिए उत्सुक हूं। – JDong

+0

@ मार्क - डेड लिंक। – ArtOfWarfare

उत्तर

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." 

से wxPython का उपयोग कर http://ubuntuforums.org/showpost.php?p=2681009&postcount=5

+0

यह ग्लैड और जल्दी से जीयूआई आधारित एप्लिकेशन में काम नहीं करता है, क्या आप इस कोड को बेहतर बना सकते हैं। –

+0

जब मैं इस कोड को निष्पादित करता हूं (वर्चुअलबॉक्स में लिनक्स टकसाल 16 का उपयोग करके) परिणामस्वरूप छवि पूरी तरह से काला होती है। क्या आपको कोई विचार है क्यों? – bab

+0

कभी-कभी रंगों का एन्कोडिंग बंद होता है। यह काफी परेशान है। देखें कि https://github.com/JDong820/neobot/blob/master/Linux/Robot/screen.py आपकी कोई मदद है; get_rowstride को कॉल नोटिस करें। – JDong

3

एक छोटी सी खोज gtkShots दिखाई देती है जैसे यह आपकी मदद कर सकती है, क्योंकि यह एक जीपीएलड पायथन स्क्रीनशॉट प्रोग्राम है, इसलिए इसमें आपको जो चाहिए वह होना चाहिए।

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

पायथन इमेजिंग पुस्तकालय की आवश्यकता है

+18

केवल विंडोज पर काम करता है: http://www.pythonware.com/library/ पायल/हैंडबुक/imagegrab.htm – bernie

18

यह एक X11 पर काम करता है, और Windows पर शायद भी (किसी के लिए, कृपया संपर्क करें)। जरूरत PyQt4:

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

कृपया पीईक्यूटी के लाइसेंसिंग पर ध्यान दें, जो पायथन और क्यूटी से अधिक प्रतिबंधित है। http://www.riverbankcomputing.co.uk/software/pyqt/license – user120242

+0

उपयोगकर्ता kmilin (नीचे) रिपोर्ट करता है कि यह विंडोज –

+0

पर काम करता है यह एकमात्र समाधान है जो मेरे लिनक्स इंस्टॉलेशन "आउट ऑफ़ द बॉक्स" पर चलता है । मुझे नहीं पता क्यों, लेकिन मेरे पास PyQx4 है, जबकि पीईडब्ल्यूएक्स, पीईजीटीके, इमेजग्राब की कमी है। - धन्यवाद :)। –

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) 
+0

पाइथन कोड के भीतर टिप्पणियां, स्पष्टीकरण और संदर्भ के साथ संदर्भ। http://www.blog.pythonlibrary.org/2010/04/16/how-to-take-a-creenshot-of-your-wxpython-app-and-print-it/ या http://www.blog .pythonlibrary.org/2010/04/16/how-to-take-a-screenshot-of-your-wxpython-app-and-print-it/ – Civilian

41

एक कक्षा में सभी जवाब संकलित करें। आउटपुट पीआईएल छवि।

#!/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() 
+0

मुझे नहीं पता कि wxwidgets में कोई बदलाव आया है या नहीं यह पोस्ट, लेकिन 'getScreenByWx' विधि' wx._core.PyNoAppError के साथ विफल हो जाती है: wx.App ऑब्जेक्ट पहले बनाया जाना चाहिए! '। काफी हद तक, कोड ठीक काम करता है अगर आप पाइथन खोल में लाइन से लाइन में प्रवेश कर रहे हैं लेकिन एक स्क्रिप्ट में यह विफल हो जाता है। – CadentOrange

+0

आपको अपने कोड का परीक्षण करना चाहिए! या, नहीं, अगर आप इसे प्रकाशित कर रहे हैं ... 'getScreenByWx' में आपको ए चाहिए) 'mybitmap' को' bmp' 'से बदलें और b)' wx.App()' को एक चर में सहेजें। 'GetScreenByGtk'' में बदलें '(pb! = None) '' pb' कोई नहीं है '। और क्यूटी का उपयोग न करें - आप दो बार 'QAplication' नहीं बना सकते - आपका ऐप दूसरी बार बनाने की कोशिश पर क्रैश हो जाएगा। – Jury

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') 
+0

आयात त्रुटि: नाम आयात नहीं कर सकता gtkpixbuf –

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 में बाधाओं-फ़ाइलों में कुछ प्रकारों को हल करें, और उसके बाद साइथन का उपयोग करके संकलित करें । इससे गति थोड़ी बढ़ सकती है।


संपादित करें:

#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); 
} 

और फिर अजगर: हम सी में समारोह के मुख्य लिख सकते हैं, और फिर ctypes से अजगर में इसका इस्तेमाल करते हैं, यहाँ कुछ मैं एक साथ काट दिया है -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() 
+2

यह अन्य उत्तरों की तुलना में कम से कम वोट नहीं होने पर सोने के लायक है। ठोस काम और एक मूल भी! चीयर्स! – Torxed

+1

जो तेजी से ढूंढ रहे हैं उनके लिए: यह दृष्टिकोण आकार 1000 x 1000 के चित्र के लिए औसतन ~ 25ms लेता है। – Mrlenny

+1

@JHolta, क्या आप कैप्चर की गई छवि की गुणवत्ता को बदलने का एक तरीका जानते हैं? (और भी तेज करने के लिए) – Mrlenny

-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." 
+1

यह बकवास क्या है? आधे आयात बेकार हैं, वहां एक 'लूप' है जो कभी भी बाहर नहीं निकलता है (और 'True' के बजाय' 1' का उपयोग करता है), 'if (pb! = None)' है, 'केवल' अगर pb: 'के बजाय, कुछ है व्यर्थ कच्चे तार। – ArtOfWarfare

2

इस Autopy

बिटमैप मॉड्यूल के लिए एक अजगर पैकेज हथियाने स्क्रीन करने के लिए कर सकते है (bitmap.capture_screen) यह multiplateform (विंडोज, लिनक्स, OSX) है।

0

यह एक पुराना सवाल है। मैं नए उपकरणों का उपयोग करके इसका जवाब देना चाहता हूं।

पायथन 3 के साथ काम करता है (पाइथन 2 के साथ काम करना चाहिए, लेकिन मैंने इसका परीक्षण नहीं किया है) और पीईक्यूटी 5।

न्यूनतम कार्य उदाहरण। इसे पायथन खोल में कॉपी करें और परिणाम प्राप्त करें।

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

क्या आपको इस फ़ंक्शन को पूरा करने के लिए औसत समय मिला है? इसके लायक होने पर बस ब्याज – Mrlenny

+1

@Mrlenny 300 ms (पूर्ण कोड के लिए), 165 एमएस (कोड की अंतिम तीन पंक्तियां)। – rominf

2

थोड़ी देर हो चुकी है, लेकिन कोई बात नहीं आसान एक

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

है मैं नहीं pyscreenshot या scrot साथ लिनक्स में स्क्रीनशॉट ले सकता है क्योंकि pyscreenshot के उत्पादन में था सिर्फ एक ब्लैक स्क्रीन पीएनजी छवि फ़ाइल।

लेकिन भगवान का शुक्र है कि कुछ भी इंस्टॉल किए बिना लिनक्स में स्क्रीनशॉट लेने का एक और आसान तरीका था। //linux.die: सिर्फ 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 
संबंधित मुद्दे