it-swarm-es.tech

Tome una captura de pantalla a través de un script de Python en Linux

Quiero tomar una captura de pantalla a través de un script de python y guardarlo discretamente.

Solo me interesa la solución de Linux, y debería admitir cualquier entorno basado en X.

77
skyronic

Esto funciona sin tener que usar scrot o 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."

Obtenido de http://ubuntuforums.org/showpost.php?p=2681009&postcount=5

64
Rusty

Compila todas las respuestas en una clase. Salidas de imagen 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 __== '__main__':
    s = screengrab()
    screen = s.screen()
    screen.show()
46
Alex Snet

Solo para completar: Xlib - Pero es un poco lento al capturar toda la pantalla:

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

Uno podría tratar de trow algunos tipos en los archivos de cuello de botella en PyXlib, y luego compilarlo usando Cython. Eso podría aumentar un poco la velocidad.


Editar: Podemos escribir el núcleo de la función en C, y luego usarlo en Python desde ctypes, aquí hay algo que hackeé juntos:

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

Y luego el archivo python:

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 __== '__main__':
  im = grab_screen(0,0,1440,900)
  im.show()
34
JHolta

Este funciona en X11, y quizás también en Windows (alguien, por favor, verifique). Necesidades PyQt4 :

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

Tengo un proyecto contenedor ( pyscreenshot ) para scrot, imagemagick, pyqt, wx y pygtk. Si tienes uno de ellos, puedes usarlo. Todas las soluciones están incluidas en esta discusión.

Instalar:

easy_install pyscreenshot

Ejemplo:

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')
15
ponty

Solución multiplataforma utilizando 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)
8
Snowball
import ImageGrab
img = ImageGrab.grab()
img.save('test.jpg','JPEG')

esto requiere Python Imaging Library

7
Slava V

Puedes usar esto

import os
os.system("import -window root screen_shot.png")
3
Ahir Kamlesh

Una búsqueda breve apareció gtkShots parece que podría serle de ayuda, ya que es un programa de captura de pantalla de Python con GPL, por lo que debería tener todo lo que necesita.

3
Douglas Leeder

un poco tarde, pero no importa fácil es uno

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

Hay un paquete de python para esto Autopy

El módulo de mapa de bits se puede capturar en pantalla (bitmap.capture_screen) Es multiplataforma (Windows, Linux, Osx).

2
ouille

Hace poco escribí un paquete que toma una captura de pantalla con la biblioteca X11 y devuelve la imagen como una matriz numpy. De hecho, utilicé algunas sugerencias que se mencionan en este hilo y las mejoré. Una velocidad de cuadro típica de 60+ fps para una resolución de 1080p es posible en una máquina moderna. En realidad, en mi máquina de desarrollo (que tiene ~ 3 años) logré obtener 200 fps. Aquí está el enlace al proyecto https://github.com/mherkazandjian/fastgrab

1
mher

No pude tomar una captura de pantalla en Linux con pyscreenshot o scrot porque la salida de pyscreenshot era solo un archivo de imagen png de pantalla negra.

pero gracias a Dios, había otra manera muy fácil de hacer capturas de pantalla en Linux sin instalar nada. simplemente coloque el código a continuación en su directorio y ejecute con python demo.py

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

también hay muchas opciones disponibles para 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
1
cyera

De este hilo :

 import os
 os.system("import -window root temp.png")
1
anderstood

Es una vieja pregunta. Me gustaría responderlo utilizando nuevas herramientas.

Funciona con python 3 (debería funcionar con python 2, pero no lo he probado) y PyQt5.

Ejemplo de trabajo mínimo. Cópialo en el shell de python y obtén el resultado.

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