it-swarm-id.com

Ambil tangkapan layar melalui skrip python. [Linux]

Saya ingin mengambil tangkapan layar melalui skrip python dan secara diam-diam menyimpannya.

Saya hanya tertarik pada solusi Linux, dan harus mendukung lingkungan berbasis X.

75
skyronic

Ini berfungsi tanpa harus menggunakan scrot atau 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."

Dipinjam dari http://ubuntuforums.org/showpost.php?p=2681009&postcount=5

64
Rusty

Kompilasi semua jawaban dalam satu kelas . Keluarkan gambar 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()
45
Alex Snet

Hanya untuk kelengkapan: Xlib - Tapi agak lambat saat menangkap seluruh layar:

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

Orang bisa mencoba menyadap beberapa jenis dalam bottleneck-file di PyXlib, dan kemudian mengompilasinya menggunakan Cython. Itu bisa meningkatkan kecepatan sedikit.


Edit: Kita dapat menulis inti dari fungsi dalam C, dan kemudian menggunakannya dalam python dari ctypes, berikut adalah sesuatu yang saya retas bersama:

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

Dan kemudian 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()
34
JHolta

Yang ini berfungsi pada X11, dan mungkin juga pada Windows (seseorang, silakan periksa) Kebutuhan PyQt4 :

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

Saya memiliki proyek pembungkus ( pyscreenshot ) untuk scrot, imagemagick, pyqt, wx dan pygtk . Jika Anda memiliki salah satu dari mereka, Anda dapat menggunakannya . Semua solusi disertakan dari diskusi ini.

Memasang:

easy_install pyscreenshot

Contoh:

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

Solusi lintas platform menggunakan 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')

ini membutuhkan Python Imaging Library

7
Slava V

Pencarian singkat muncul gtkShots sepertinya itu mungkin membantu Anda, karena ini adalah program screenshot python GPLed, jadi Anda harus memiliki apa yang Anda butuhkan.

3
Douglas Leeder

agak terlambat tapi tidak pernah mudah

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

Ada paket python untuk Autopy ini

Modul bitmap dapat melakukan screen grabbing (bitmap.capture_screen) Ini adalah bentuk multiplate (Windows, Linux, Osx).

2
ouille

Anda bisa menggunakan ini

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

Saya tidak dapat mengambil screenshot di Linux dengan pyscreenshot atau scrot karena output dari pyscreenshot hanyalah file gambar png layar hitam.

tapi syukurlah ada cara lain yang sangat mudah untuk mengambil tangkapan layar di Linux tanpa menginstal apa pun. cukup letakkan kode di bawah ini di direktori Anda dan jalankan dengan python demo.py

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

juga ada banyak opsi yang tersedia untuk 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

Dari utas ini :

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

Baru-baru ini saya menulis paket yang mengambil tangkapan layar menggunakan pustaka X11 dan mengembalikan gambar sebagai array numpy. Saya benar-benar menggunakan beberapa saran yang disebutkan dalam utas ini dan diperbaiki. Frame rate tipikal 60+ fps .__ untuk resolusi 1080p dimungkinkan pada mesin modern. Sebenarnya pada pengembangan saya. Mesin .__ (yaitu ~ 3 tahun) saya berhasil mendapatkan 200 fps. di sini adalah tautan ke proyek https://github.com/mherkazandjian/fastgrab

0
mher

Itu pertanyaan lama. Saya ingin menjawabnya menggunakan alat baru.

Bekerja dengan python 3 (harus bekerja dengan python 2, tapi saya belum mengujinya) dan PyQt5.

Contoh kerja minimal. Salin ke Shell python dan dapatkan hasilnya.

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