it-swarm-vi.tech

Chụp ảnh màn hình thông qua một kịch bản python. [Linux]

Tôi muốn chụp ảnh màn hình thông qua một kịch bản python và lưu nó một cách không phô trương.

Tôi chỉ quan tâm đến giải pháp Linux và nên hỗ trợ mọi môi trường dựa trên X.

75
skyronic

Điều này hoạt động mà không phải sử dụng Scrot hoặc 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."

Mượn từ http://ubuntuforums.org/showpost.php?p=2681009&postcount=5

64
Rusty

Tổng hợp tất cả các câu trả lời trong một lớp . Xuất hình ảnh 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

Chỉ để hoàn thiện: Xlib - Nhưng nó hơi chậm khi chụp toàn bộ màn hình:

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

Người ta có thể thử truy xuất một số loại trong tệp cổ chai trong PyXlib, sau đó biên dịch nó bằng Cython. Điều đó có thể tăng tốc độ một chút.


Chỉnh sửa: Chúng ta có thể viết lõi của hàm trong C, và sau đó sử dụng nó trong python từ ctypes, đây là thứ tôi đã hack cùng nhau:

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

Và sau đó là tập tin 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

Cái này hoạt động trên X11 và có lẽ trên Windows cũng vậy (ai đó, vui lòng kiểm tra). Nhu cầu PyQt4 :

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

Tôi có một dự án trình bao bọc ( p chọc cao ) cho Scrot, fantemagick, pyqt, wx và pygtk . Nếu bạn có một trong số chúng, bạn có thể sử dụng nó . Tất cả các giải pháp đều được đưa vào thảo luận này.

Cài đặt, dựng lên:

easy_install pyscreenshot

Thí dụ:

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

Giải pháp đa nền tảng sử dụng 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')

điều này đòi hỏi Thư viện hình ảnh Python

7
Slava V

Một tìm kiếm ngắn đã bật lên gtkShots có vẻ như nó có thể giúp bạn, vì đó là chương trình chụp màn hình python GPLed, vì vậy nên có những gì bạn cần trong đó.

3
Douglas Leeder

hơi muộn nhưng không bao giờ dễ dàng

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

Có một gói python cho điều này Autopy

Mô-đun bitmap có thể để chụp màn hình (bitmap.capture_screen) Đây là dạng đa dạng (Windows, Linux, Osx).

2
ouille

Bạn có thể sử dụng cái này

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

Tôi không thể chụp ảnh màn hình trong Linux bằng p chọc trời hoặc màn hình vì đầu ra của pyscreenshot chỉ là tệp hình ảnh png màn hình đen.

nhưng cảm ơn chúa, có một cách rất dễ dàng khác để chụp ảnh màn hình trong Linux mà không cần cài đặt gì. chỉ cần đặt mã bên dưới vào thư mục của bạn và chạy với python demo.py

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

cũng có nhiều tùy chọn có sẵn cho 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

Từ chủ đề này :

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

Gần đây tôi đã viết một gói chụp ảnh màn hình bằng thư viện X11 và trả về hình ảnh dưới dạng một mảng numpy. Tôi thực sự đã sử dụng một số gợi ý là Được đề cập trong chủ đề này và cải thiện chúng. Tốc độ khung hình thông thường là 60+ khung hình/giây Cho độ phân giải 1080p là có thể trên một máy hiện đại. Trên thực tế về sự phát triển của tôi Máy (tức là ~ 3 tuổi) tôi đã đạt được 200 khung hình/giây. đây là liên kết đến dự án https://github.com/mherkazandjian/fastgrab

0
mher

Đó là một câu hỏi cũ. Tôi muốn trả lời nó bằng các công cụ mới.

Hoạt động với python 3 (nên hoạt động với python 2, nhưng tôi chưa kiểm tra nó) và PyQt5.

Ví dụ làm việc tối thiểu. Sao chép nó vào Shell python và nhận được kết quả.

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