파이썬 스크립트를 통해 스크린 샷을 찍고 눈에 띄지 않게 저장하고 싶습니다.
저는 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에서 파이썬으로 사용할 수 있습니다. 여기에 제가 함께 해킹 한 것이 있습니다.
#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);
}
그리고 파이썬 파일 :
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가 필요합니다.