it-swarm-tr.com

Bir python betiği ile bir ekran görüntüsü alın. [Linux]

Bir python betiği ile ekran görüntüsü almak ve göze çarpmadan kaydetmek istiyorum.

Yalnızca Linux çözümüyle ilgileniyorum ve X tabanlı herhangi bir ortamı desteklemeliyim.

75
skyronic

Bu, scrot veya ImageMagick kullanmak zorunda kalmadan çalışır.

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

http://ubuntuforums.org/showpost.php?p=2681009&postcount=5 den ödünç alındı

64
Rusty

Tüm cevapları bir sınıfta topla ..__ PIL görüntüsünü çıkarır.

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

Sadece tamlık için: Xlib - Ama tüm ekranı çekerken biraz yavaş:

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

Birileri PyXlib'deki darboğaz dosyalarındaki bazı türleri atmaya ve Cython kullanarak derlemeye çalışabilir. Bu hızı biraz arttırabilir.


Edit: Bu fonksiyonun çekirdeğini C dilinde yazabiliriz ve sonra ctypes'den python olarak kullanabiliriz, işte birlikte hacklendiğim bir şey

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

Ve sonra python dosyası:

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

Bu, X11'de ve belki de Windows'ta da çalışıyor (birisi, lütfen kontrol edin). İhtiyaçlar PyQt4 :

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

Scrot, imagemagick, pyqt, wx ve pygtk .. için bir sarmalayıcı projem var ( pyscreenshot ) .. Onlardan bir tane varsa, onu kullanabilirsiniz . Tüm çözümler bu tartışmaya dahil edilmiştir.

Yükleyin:

easy_install pyscreenshot

Örnek:

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

wxPython kullanarak çapraz platform çözümü

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

bu Python Görüntüleme Kütüphanesi gerektirir

7
Slava V

Kısa bir arama yapıldı gtkShots bir GPLed python ekran görüntüsü programı olduğundan size yardımcı olabilir gibi görünüyor, bu yüzden ihtiyacınız olana sahip olmalısınız.

3
Douglas Leeder

biraz geç ama boşuna kolay olanı

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

Bunun için bir python paketi var Autopy

Bitmap modülü kapma taramasını yapabilir (bitmap.capture_screen)

2
ouille

Bunu kullanabilirsin

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

Linux'ta ekran görüntüsünü pyscreenshot veya scrot ile çekemedim çünkü pyscreenshot çıktısı sadece siyah ekran png görüntü dosyasıydı.

ama şükürler olsun ki, Linux'ta ekran görüntüsü almak için hiçbir şey yüklemeden başka bir kolay yol vardı. Sadece dizinin altına kodu koyup python demo.py ile çalıştırın

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

ayrıca gnome-screenshot --help için birçok seçenek mevcut

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

/ bu konudan :

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

Geçenlerde X11 kütüphanesini kullanarak ekran görüntüsü alan bir paket yazdım ve görüntüyü mide dizisi olarak döndürdüm. Aslında, bu başlıkta belirtilen ve...... Modern bir makinede 1080p çözünürlükte 60+ fps Aslında benim gelişimimde Makinede (yani ~ 3 yaşında) 200 fps almayı başardım. işte... projenin bağlantısı https://github.com/mherkazandjian/fastgrab

0
mher

Bu eski bir soru. Yeni araçlar kullanarak cevaplamak istiyorum.

Python 3 ile çalışır (python 2 ile çalışması gerekir, ancak test etmedim) ve PyQt5.

Minimal çalışma örneği Python Kabuğuna kopyala ve sonucu al.

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