92 votes

Prendre une capture d'écran via un script python. [Linux]

Je veux prendre une capture d'écran via un script python et l'enregistrer discrètement.

Je ne suis intéressé que par la solution Linux, et devrait supporter tout environnement basé sur X.

0 votes

Une raison pour laquelle vous ne pouvez pas utiliser scrotum ?

0 votes

Je suis curieux de vérifier les performances des méthodes suggérées ci-dessous.

4 votes

65voto

Rusty Points 601

Cela fonctionne sans avoir à utiliser scrot ou 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."

Emprunté auprès de http://ubuntuforums.org/showpost.php?p=2681009&postcount=5

0 votes

Cela ne fonctionne pas dans une application basée sur une interface graphique utilisant Glade et rapidement, pouvez-vous améliorer ce code.

0 votes

Lorsque j'exécute ce code (en utilisant linux mint 16 dans virtualbox) l'image résultante est complètement noire. Avez-vous une idée de la raison ?

0 votes

Parfois, l'encodage des couleurs n'est pas correct. C'est assez gênant. Regardez si github.com/JDong820/neobot/blob/master/Linux/Robot/screen.py est d'une quelconque aide pour vous ; remarquez l'appel à get_rowstride.

50voto

Alex Snet Points 296

Compile toutes les réponses dans une classe. Produit une image LIP.

#!/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 != 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 votes

Je ne sais pas s'il y a eu une modification de wxWidgets depuis ce post, mais la fonction getScreenByWx échoue avec wx._core.PyNoAppError: The wx.App object must be created first! . De manière assez amusante, le code fonctionne bien si vous l'entrez ligne par ligne dans le shell python mais dans un script il échoue.

0 votes

Vous devriez tester votre code ! Ou, pas le vôtre, si vous le publiez... Sur getScreenByWx vous devez a) remplacer myBitmap par bmp et b) sauver wx.App() dans une variable. Dans getScreenByGtk remplacer (pb != None) à pb is None . Et ne pas utiliser Qt ainsi - vous ne pouvez pas créer deux fois QApplication - votre application va se planter si vous essayez de la créer une deuxième fois.

19voto

Juliano Points 13802

Celui-ci fonctionne sous X11, et peut-être aussi sous Windows (quelqu'un peut vérifier). Nécessite PyQt4 :

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

2 votes

Veuillez prendre note de la licence de PyQt, qui est plus restrictive que celle de Python et de Qt. riverbankcomputing.co.uk/software/pyqt/license

0 votes

C'est la seule solution qui fonctionne sur mes installations Linux "out-of-the-box". Je ne sais pas pourquoi, mais j'ai PyQt4 partout, alors qu'il manque PyWX, PyGtk, ImageGrab. - Merci :).

0 votes

Le code vient de fonctionner (sur Windows 7 x64 - Python 2.7.5 ; distribution Pythonxy). Jpeg aussi disponible (e.g. ... .save('d:/test.jpg', 'jpeg'))

18voto

ponty Points 266

J'ai un projet enveloppant ( pyscreenshot ) pour scrot, imagemagick, pyqt, wx et pygtk. Si vous avez l'un d'entre eux, vous pouvez l'utiliser. Toutes les solutions sont incluses à partir de cette discussion.

Installez :

easy_install pyscreenshot

Exemple :

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 votes

ImportError : impossible d'importer le nom gtkpixbuf

0 votes

Il me donne cette erreur : pyscreenshot.tempexport.RunProgError: No protocol specified giblib error: Can't open X display. It *is* running, yeah?" timeout_happened=False>

9voto

Snowball Points 86

Solution multiplateforme utilisant wxPython :

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 votes

Références, avec commentaires, explications et contexte dans le code python. blog.pythonlibrary.org/2010/04/16/ ou blog.pythonlibrary.org/2010/04/16/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X