Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
[c][gtk][webkit]get screenshot PNG from web page
/*
* get screenshot PNG from web page
*
* build:
* FLAGS=`pkg-config --cflags --libs gtk+-x11-2.0 glib-2.0 webkit-1.0`
* gcc -Wall $FLAGS getscreenshot.c -o getscreenshot
*
* usage:
* /usr/bin/xvfb-run -s "-screen 0 1024x768x24" ./getscreenshot test.html
*
*/
#include <glib.h>
#include <glib/gprintf.h>
#include <gtk/gtk.h>
#include <webkit/webkit.h>
typedef struct _ThumbInfo ThumbInfo;
struct _ThumbInfo {
gint width;
gint height;
GString * filename;
};
typedef struct _FontInfo FontInfo;
struct _FontInfo {
gint point;
GString * name;
};
/*
* see: http://webkitgtk.org/reference/webkitgtk-WebKitWebView.html signals
*/
static void
loaded(WebKitWebView * view, WebKitWebFrame * frame, gpointer data)
{
ThumbInfo * thumb;
GdkWindow * window;
GdkColormap * colormap;
gint width;
gint height;
GdkPixbuf * pixbuf;
GdkPixbuf * thumb_buf;
thumb = data;
g_object_get(G_OBJECT(view), "window", &window, NULL);
gdk_window_get_size(GDK_WINDOW(window), &width, &height);
colormap = gdk_window_get_colormap(GDK_WINDOW(window));
/* gdk-pixbuf api: http://library.gnome.org/devel/gdk-pixbuf/stable/ */
pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, width, height);
thumb_buf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,
thumb->width, thumb->height);
gdk_pixbuf_get_from_drawable(pixbuf, GDK_DRAWABLE(window), colormap,
0, 0, 0, 0, width, height);
gdk_pixbuf_scale(pixbuf, thumb_buf,
0, 0, thumb->width, thumb->height,
0.0, 0.0,
thumb->width / (double) width,
thumb->height / (double) height,
GDK_INTERP_HYPER);
gdk_pixbuf_save(thumb_buf, thumb->filename->str, "png", NULL, NULL);
g_object_unref(G_OBJECT(pixbuf));
g_object_unref(G_OBJECT(thumb_buf));
g_printf("saved %dx%d PNG into %s\n",
thumb->width, thumb->height, thumb->filename->str);
gtk_main_quit();
}
static GtkWidget *
init_window(GString * url, ThumbInfo * thumb, FontInfo * font)
{
GtkWidget * window;
GtkWidget * webview;
GdkScreen * screen;
WebKitWebSettings * settings;
screen = gdk_screen_get_default();
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_move(GTK_WINDOW(window), 0, 0);
gtk_window_resize(GTK_WINDOW(window),
gdk_screen_get_width(screen),
gdk_screen_get_height(screen));
webview = webkit_web_view_new();
/* webkit settings props:
* http://webkitgtk.org/reference/webkitgtk-WebKitWebSettings.html
*/
settings = webkit_web_settings_new();
g_object_set(G_OBJECT(settings),
"serif-font-family", font->name->str,
"sans-serif-font-family", font->name->str,
"monospace-font-family", font->name->str,
"default-font-family", font->name->str,
"default-font-size", font->point,
NULL);
webkit_web_view_set_settings(WEBKIT_WEB_VIEW(webview), settings);
gtk_container_add(GTK_CONTAINER(window), webview);
gtk_signal_connect(GTK_OBJECT(webview), "load-finished",
GTK_SIGNAL_FUNC(loaded), thumb);
webkit_web_view_open(WEBKIT_WEB_VIEW(webview), url->str);
gtk_widget_show_all(window);
return window;
}
static void
parse_option(gint * pargc, gchar ** pargv[],
ThumbInfo * thumb, FontInfo * font)
{
/* glib commandline option parser:
* http://library.gnome.org/devel/glib/stable/
*/
GOptionContext *context;
gchar * filename = NULL;
gchar * fontname = NULL;
GOptionEntry entries[] = {
{"width", 'w', 0, G_OPTION_ARG_INT,
&thumb->width,
"thumbnail width pixel", "WIDTH"},
{"height", 'h', 0, G_OPTION_ARG_INT,
&thumb->height,
"thumbnail height pixel", "HEIGHT"},
{"output", 'o', G_OPTION_FLAG_FILENAME, G_OPTION_ARG_FILENAME,
&filename,
"thumbnail PNG file name", "PNG_FILENAME"},
{"font", 'f', 0, G_OPTION_ARG_STRING,
&fontname,
"font name", "FONT_NAME"},
{"point", 'p', 0, G_OPTION_ARG_INT,
&font->point,
"default font point", "POINT"},
{NULL}
};
context = g_option_context_new("get web page thumbnail");
g_option_context_add_main_entries(context, entries, NULL);
/* gtk_get_option_group see:
* http://library.gnome.org/devel/gtk/stable/gtk-General.html */
g_option_context_add_group(context, gtk_get_option_group(TRUE));
if (!g_option_context_parse(context, pargc, pargv, NULL)) {
gtk_exit(0);
}
if (filename) {
g_string_overwrite(thumb->filename, 0, filename);
}
if (fontname) {
g_string_overwrite(font->name, 0, fontname);
}
g_option_context_free(context);
}
gint
main(gint argc, gchar * argv[])
{
GString * url;
ThumbInfo thumb;
FontInfo font;
GtkWidget * window;
font.point = 14;
font.name = g_string_new("VLGothic");
thumb.width = 200;
thumb.height = 150;
thumb.filename = g_string_new("screenshot.png");
g_thread_init(NULL);
gdk_threads_init();
gdk_threads_enter();
parse_option(&argc, &argv, &thumb, &font);
url = g_string_new(argv[1]);
if (!g_str_has_prefix(url->str, "http")) {
url = g_string_prepend(url, "file://");
}
window = init_window(url, &thumb, &font);
gtk_main();
gdk_threads_leave();
g_string_free(url, TRUE);
g_string_free(font.name, TRUE);
g_string_free(thumb.filename, TRUE);
return 0;
}
@mattn
Copy link

mattn commented Nov 9, 2010

cool

@codebrainz
Copy link

codebrainz commented Sep 3, 2011

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment