我想通过python脚本截取屏幕截图并且不引人注意地保存它.
我只对Linux解决方案感兴趣,应该支持任何基于X的环境.
这不需要使用scrot或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."
借用http://ubuntuforums.org/showpost.php?p=2681009&postcount=5
在一个班级编译所有答案.输出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 __name__ == '__main__': s = screengrab() screen = s.screen() screen.show()
只是为了完整性:Xlib - 但是在捕获整个屏幕时它有点慢:
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()
可以尝试在PyXlib中的瓶颈文件中输入一些类型,然后使用Cython进行编译.这可能会提高速度.
编辑: 我们可以在C中编写函数的核心,然后在ctypes的python中使用它,这是我一起攻击的东西:
#include#include #include //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); }
然后是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 __name__ == '__main__': im = grab_screen(0,0,1440,900) im.show()
这个适用于X11,也许也适用于Windows(有人,请检查).需要PyQt4:
import sys from PyQt4.QtGui import QPixmap, QApplication app = QApplication(sys.argv) QPixmap.grabWindow(QApplication.desktop().winId()).save('test.png', 'png')
我有一个用于scrot,imagemagick,pyqt,wx和pygtk 的包装器项目(pyscreenshot).如果你有其中一个,你可以使用它.所有解决方案都包含在本讨论中.
安装:
easy_install pyscreenshot
例:
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')
使用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')
这需要Python Imaging Library