Voglio prendere uno screenshot tramite uno script python e salvarlo in modo discreto.
Mi interessa solo la soluzione Linux e dovrei supportare qualsiasi ambiente basato su X.
Funziona senza dover usare 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."
Prelevato da http://ubuntuforums.org/showpost.php?p=2681009&postcount=5
Compilare tutte le risposte in una classe . Immagine PIL delle uscite.
#!/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()
Solo per completezza: Xlib - Ma è un po 'lento quando si cattura l'intero schermo:
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()
Si potrebbe provare a lanciare alcuni tipi nei file bottleneck in PyXlib, e poi compilarlo usando Cython. Questo potrebbe aumentare un po 'la velocità.
Modifica: Possiamo scrivere il nucleo della funzione in C, e poi usarlo in python da ctypes, ecco qualcosa che ho violato insieme:
#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);
}
E poi il file 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()
Questo funziona su X11, e forse anche su Windows (qualcuno, per favore controlla). Esigenze PyQt4 :
import sys
from PyQt4.QtGui import QPixmap, QApplication
app = QApplication(sys.argv)
QPixmap.grabWindow(QApplication.desktop().winId()).save('test.png', 'png')
Ho un progetto wrapper ( pyscreenshot ) per scrot, imagemagick, pyqt, wx e pygtk . Se ne hai uno, puoi usarlo . Tutte le soluzioni sono incluse in questa discussione.
Installare:
easy_install pyscreenshot
Esempio:
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')
Soluzione multipiattaforma usando 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')
questo richiede la libreria di immagini Python
Una breve ricerca ha mostrato gtkShots sembra che potrebbe aiutarti, dato che si tratta di un programma di screenshot di Python GPL, quindi dovresti avere ciò che ti serve.
un po 'in ritardo, ma non è difficile
import autopy
import time
time.sleep(2)
b = autopy.bitmap.capture_screen()
b.save("C:/Users/mak/Desktop/m.png")
C'è un pacchetto Python per questo Autopy
Il modulo bitmap può eseguire lo screen grabbing (bitmap.capture_screen) È multipiattaforma (Windows, Linux, Osx).
Puoi usare questo
import os
os.system("import -window root screen_shot.png")
Non sono riuscito a fare screenshot su Linux con pyscreenshot o scrot perché l'output di pyscreenshot
era solo un file di immagine png su schermo nero.
ma grazie a dio c'era un altro modo molto semplice per fare screenshot su Linux senza installare nulla. metti sotto il codice nella tua directory ed esegui con python demo.py
import os
os.system("gnome-screenshot --file=this_directory.png")
inoltre ci sono molte opzioni disponibili per 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
Da questa discussione :
import os
os.system("import -window root temp.png")
Recentemente ho scritto un pacchetto che cattura uno screenshot usando la libreria X11 e restituisce l'immagine come una serie numpy. In realtà ho usato alcuni suggerimenti che sono Menzionati in questa discussione e migliorati su di essi. Su una macchina moderna è possibile una frequenza fotogrammi tipica di 60+ fps Per una risoluzione 1080p. In realtà sul mio sviluppo Machine (che ha ~ 3 anni) sono riuscito a ottenere 200 fps. ecco il link al progetto https://github.com/mherkazandjian/fastgrab
È una vecchia domanda. Mi piacerebbe rispondere usando nuovi strumenti.
Funziona con python 3 (dovrebbe funzionare con Python 2, ma non l'ho testato) e PyQt5.
Esempio di lavoro minimo. Copialo su Python Shell e ottieni il risultato.
from PyQt5.QtWidgets import QApplication
app = QApplication([])
screen = app.primaryScreen()
screenshot = screen.grabWindow(QApplication.desktop().winId())
screenshot.save('/tmp/screenshot.png')