Frage

Ich möchte einen Screenshot über ein Python-Skript nehmen und es unauffällig speichern.

Ich bin nur daran interessiert, in der Linux-Lösung, und soll all X-basierte Umgebung unterstützen.

War es hilfreich?

Lösung

Das funktioniert ohne scrot oder ImageMagick verwenden zu müssen.

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

Borrowed von http://ubuntuforums.org/showpost.php?p=2681009&postcount= 5

Andere Tipps

Übersetzen alle Antworten in einer Klasse. Ausgänge PIL Bild.

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

Nur der Vollständigkeit halber: Xlib - Aber es ist etwas langsam, wenn der ganze Bildschirm erfassen:

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

Man könnte versuchen, einige Arten in den Engpass-Dateien in PyXlib trow und dann kompiliert Cython verwenden. Das könnte die Geschwindigkeit ein wenig erhöhen.


Edit: Wir können den Kern der Funktion in C schreiben, und es dann von ctypes in Python verwenden, hier ist etwas, das ich zusammen gehackt:

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

Und dann der Python-Datei:

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

Dies funktioniert auf X11 und vielleicht auch auf Windows (jemand, bitte ankreuzen). Benötigt PyQt4 :

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

Ich habe ein Wrapper-Projekt ( pyscreenshot ) für scrot, ImageMagick, pyqt, wx und pygtk. Wenn Sie einen von ihnen haben, können Sie es verwenden. Alle Lösungen sind aus dieser Diskussion einbezogen.

Installieren:

easy_install pyscreenshot

Beispiel:

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

Cross-Plattform-Lösung 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)
import ImageGrab
img = ImageGrab.grab()
img.save('test.jpg','JPEG')

Dies erfordert Python Imaging Library

Eine kurze Suche aufgedreht gtkShots sieht aus wie es Ihnen helfen könnte, wie es ist ein Unterliegt der GPL python Screenshot-Programm sollte so haben, was Sie in es brauchen.

Sie können dieses verwenden,

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

Es ist ein Python-Paket für diese Autopy

Die Bitmap-Module können zum Screenen erregenden (bitmap.capture_screen) Es ist multiplateform (Windows, Linux, OSX).

bisschen spät, aber macht nichts leicht ist

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

diesen Thread :

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

Ich konnte nicht Screenshot in Linux mit pyscreenshot oder scrot weil Ausgabe von pyscreenshot nehmen nur ein schwarzer Bildschirm png Bilddatei war.

, aber Gott sei Dank gab es eine weitere sehr einfache Art und Weise Screenshot in Linux für die Aufnahme ohne etwas zu installieren. knapp unter Code setzen in Ihrem Verzeichnis und führen mit python demo.py

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

gibt auch viele Optionen für gnome-screenshot --help ist

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

Ich schrieb vor kurzem ein Paket, das einen Screenshot mit der X11-Bibliothek nimmt und gibt das Bild als numpy Array. Ich habe tatsächlich einige Vorschläge, die in diesem Thread und verbessert auf ihnen erwähnt. Eine typische Bildrate von 60+ fps für eine 1080p-Auflösung sind auf einer modernen Maschine möglich. Eigentlich auf meiner Entwicklung Maschine (dh ~ 3 Jahre alt) ich es geschafft, 200 fps zu bekommen. Hier ist der Link zu dem Projekt https://github.com/mherkazandjian/fastgrab

Es ist eine alte Frage. Ich möchte sie beantworten neue Tools.

Arbeiten mit Python 3 (soll 2 mit Python arbeiten, aber ich habe es nicht getestet) und PyQt5.

Minimal Arbeits Beispiel. Kopieren Sie es in der Python-Shell und das Ergebnis erhalten.

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

Versuchen Sie es:

#!/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."
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top