Created
July 3, 2009 13:52
-
-
Save bellbind/140102 to your computer and use it in GitHub Desktop.
[python][webkitgtk][PIL][X][tool] get web site thumbnail by webkit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
""" | |
web page screenshot by webkit | |
command usage: | |
python webkitscreenshot.py test.html | |
library usage: | |
import webkitscreenshot | |
image = webkitscreenshot.screenshot_vfb("file://test.html") | |
image.save("screenshot.png") | |
required libs: | |
- pygtk: http://www.pygtk.org/ | |
- pywebkitgtk(python-webkit): http://code.google.com/p/pywebkitgtk/ | |
- PIL: http://www.pythonware.com/products/pil/ | |
required tools and resouces: | |
- Xvfb: if you use virtual framebuffer | |
- VLGothic: as default truetype font | |
""" | |
def screenshot(url, **args): | |
""" | |
get screenshot | |
- url: screenshot url (if local file: file://...) | |
- font_size: default font size | |
- font_default: default font family | |
- font_serif: serif font | |
- font_sans_serif: sans-serif font | |
- font_monospace: monospace font | |
- size: tuple (width, height) as image size. fullscreen if None | |
- return: PIL Image object | |
""" | |
return _WebKitScreenShot(url, **args).image | |
def screenshot_vfb(url, **args): | |
""" | |
get screenshot in Xvfb | |
- same parameters and results as screenshot() | |
- size: (1024, 768) as default | |
""" | |
size = (1024, 768) | |
if "size" in args: | |
size = args["size"] | |
del args["size"] | |
pass | |
proc, screen = vfb(display_spec="%dx%dx24" % size) | |
try: | |
return screenshot(url, **args) | |
finally: | |
proc.terminate() | |
pass | |
pass | |
class _WebKitScreenShot(object): | |
""" | |
make fullscreen webkit window, then take screenshot into self.image | |
""" | |
def __init__(self, url, | |
font_size=14, | |
font_default="VLGothic", | |
font_serif="VLGothic", | |
font_sans_serif="VLGothic", | |
font_monospace="VLGothic", | |
size=None): | |
import gtk | |
import webkit | |
gtk.gdk.threads_init() | |
window = gtk.Window(gtk.WINDOW_TOPLEVEL) | |
window.move(0, 0) | |
if not size: size = (gtk.gdk.screen_width(), gtk.gdk.screen_height()) | |
window.resize(*size) | |
webview = webkit.WebView() | |
# webkit settings | |
settings = webkit.WebSettings() | |
settings.set_property("serif-font-family", font_serif) | |
settings.set_property("sans-serif-font-family", font_sans_serif) | |
settings.set_property("monospace-font-family", font_monospace) | |
settings.set_property("default-font-family", font_default) | |
settings.set_property("default-font-size", font_size) | |
webview.set_settings(settings) | |
window.add(webview) | |
webview.connect("load-finished", self._loaded) | |
webview.open(url) | |
window.show_all() | |
gtk.main() | |
gtk.gdk.threads_leave() | |
pass | |
def _loaded(self, view, frame): | |
import gtk | |
import Image | |
try: | |
width, height = view.window.get_size() | |
# see: http://www.pygtk.org/docs/pygtk/class-gdkpixbuf.html | |
pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, | |
False, 8, width, height) | |
pixbuf.get_from_drawable(view.window, view.window.get_colormap(), | |
0, 0, 0, 0, width, height) | |
self.image = Image.fromstring("RGB", (width, height), | |
pixbuf.get_pixels()) | |
except: | |
#import traceback | |
#traceback.print_exc() | |
pass | |
gtk.main_quit() | |
pass | |
pass | |
def vfb(display_spec="1024x768x24", server=0, screen=0, auto_screen=True): | |
""" | |
run Xvfb and set DISPLAY env | |
usage: | |
proc, screen = xvf() | |
import gtk | |
... | |
proc.terminate() | |
""" | |
import subprocess | |
import os | |
while True: | |
try: | |
devnull = open("/dev/null", "w") | |
proc = subprocess.Popen( | |
["Xvfb", ":%d" % server, | |
"-screen", "%d" % screen, display_spec], | |
shell=False, stdout=devnull, stderr=devnull) | |
os.environ["DISPLAY"] = ":%d.%d" % (server, screen) | |
return (proc, screen) | |
except: | |
#import traceback | |
#traceback.print_exc() | |
if not auto_screen: break | |
screen += 1 | |
pass | |
pass | |
pass | |
def _main(): | |
thumbsize = (200, 150) | |
thumbfile = "screenshot.png" | |
font = "VLGothic" | |
from optparse import OptionParser | |
parser = OptionParser() | |
parser.usage += " URL" | |
parser.add_option("-s", "--size", dest="size", | |
help="output image size: %d,%d" % thumbsize, | |
default="%d,%d" % thumbsize) | |
parser.add_option("-o", "--output", dest="output", | |
help="output image filename: %s" % thumbfile, | |
default=thumbfile) | |
parser.add_option("-f", "--font", dest="font", | |
help="default font: %s" % font, | |
default=font) | |
opts, args = parser.parse_args() | |
if len(args) == 0: | |
parser.print_help() | |
import sys | |
sys.exit(-1) | |
pass | |
thumbfile = opts.output | |
try: thumbsize = eval(opts.size) | |
except: pass | |
url = args[0] | |
if not url.startswith("http"): url = "file://" + url | |
import Image | |
image = screenshot_vfb(url, | |
font_default=font, font_sans_serif=font, | |
font_serif=font, font_monospace=font) | |
image.thumbnail(thumbsize, Image.ANTIALIAS) | |
image.save(thumbfile) | |
pass | |
if __name__ == "__main__": _main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment