XServer-less webpage screenshot – C++

Posted on April 2nd, 2009

You can follow any responses to this entry through the RSS 2.0 feed.

Someone recently pinged back my python script to create snapshots of webpages using webkit, via xvfb which didn’t require a real complete X server.

While a better solution would still be to bypass QT and render ‘by hand’ to and image file, or hack QT to do so (without requiring any X server connection, and using fewer dependency than large QT libraries…), I decided to run my script again, and I ran into troubles with python-qt4 on some debian systems (and older Fedora system, as a reader pointed out).

Anyway, I remade the script into half-proper C++ so it uses fewer dependencies, execute faster, but most of all, always links properly to QT even if the python-qt4 bindings are not working properly.

To compile, you need the QT4 dev package.


# mkdir wkthumb
# cat > wkthumb.cpp

# qmake -project
# qmake && make
# ./wkthumb

Source code after the jump

#include <qapplication>
#include <qwidget>
#include <qpainter>
#include <qtwebkit>
#include <qwebpage>
#include <qtextstream>
#include <qsize>
 
QWebView *view;
QString outfile;
 
void QWebView::loadFinished(bool ok)
{
	QTextStream out(stdout);
	if (!ok) {
		out << "Page loading failed\n";
		return;
	}
	view->page()->setViewportSize(view->page()->currentFrame()->contentsSize());
	QImage *img = new QImage(view->page()->viewportSize(), QImage::Format_ARGB32);
	QPainter *paint = new QPainter(img);
	view->page()->currentFrame()->render(paint);
	paint->end();
	if(!img->save(outfile, "png"))
		out << "Save failure\n";
	QApplication::quit();
	return;
}
 
int main(int argc, char *argv[])
{
	QTextStream out(stdout);
	if(argc < 3) {
		out << "USAGE: " << argv[0] << " <url> <outfile>\n";
		return -1;
	}
	outfile = argv[2];
	QApplication app(argc, argv);
	view = new QWebView();
	view->load(QUrl(argv[1]));
 
	return app.exec();
}

8 Responses to “XServer-less webpage screenshot – C++”

  1. Adam Nelson says:

    Will this script render external objects like Flash? It seems that the only way to get screenshots with Flash is to use a full blown XServer. Has anybody been able to do this without the XServer on Linux (or even better, Ubuntu 9.04)?

  2. Piotr Gabryjeluk says:

    Quick (damn short!) and elegant. Moreover, exactly what I need right now. I’ve used webscreenie with mentioned Xfvb, but this was not elegant.

  3. Piotr Gabryjeluk says:

    After 5 minutes of trying to compile this, I came into the following:

    * change each #include to #include
    * replace #include with these includes:

    #include
    #include
    #include

    * compile the program with the following command:

    g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I/usr/include/qt4/QtWebKit -I. -I. -I. -o wkthumb.o wkthumb.cpp

    * link the program with the following command:

    g++ -Wl,-O1 -o wkthumb wkthumb.o -L/usr/lib -lQtGui -lQtCore -lQtWebKit -lpthread

    I’m not sure how to port these compile&link instructions to qmake (probably some changes to wkthumb.pro are needed).

  4. Piotr Gabryjeluk says:

    And when running this app, you still need X server:

    ./wkthumb http://google.com google.png
    wkthumb: cannot connect to X server

  5. kang says:

    You need xvfb! not a full blown Xserver.
    For the compilation, qmake is able to regenerate the configuration so you shouldn’t need to do anything by hand either, if you have all the libs. Well in theory. Maybe a problem in your distribution/installation, i don’t know.

    For the includes, wordpress strip em out so i don’t know either which ones are involved ;) maybe you use a different version of QT.

    Finally about Flash, i don’t know either if that works. if it renders through QT somehow, that should work out. Using an open source flash plugin probably works (you only need the still image anyway)
    Good luck

  6. mariuz says:

    I have modified the #include this way (add the greater and less then signs)
    #include Qt
    #include QtGui
    #include QWebView
    #include QWebFrame

    and in wkthumb.pro i have added

    QT += network script webkit
    CONFIG += qt

    all worked ok
    the only issue i have now is with flash loading

  7. mariuz says:

    I have added view->page()->settings()->setAttribute(QWebSettings::PluginsEnabled,true);

    but still no luck even with gnash

    even if seems that is opened if you trace it with strace

    stat(“/usr/lib/gnash/libgnashplugin.so”, {st_mode=S_IFREG|0644, st_size=57592, …}) = 0
    open(“/usr/lib/gnash/libgnashplugin.so”, O_RDONLY) = 12

  8. mariuz says:

    I have added the project in gitorious
    http://gitorious.org/wkthumb

Leave a Reply