All 3 entries tagged Gtk

View all 6 entries tagged Gtk on Warwick Blogs | View entries tagged Gtk at Technorati | There are no images tagged Gtk on this blog

July 29, 2010

Milking a meme – sad Keanu comes to www2

This Greasemonkey script here adds a depiction of sad Keanu to web pages hosted at www2.warwick.ac.uk (or perhaps more accurately, webpages created using Sitebuilder hosted at www2).

For example, here he is surveying http://www2.warwick.ac.uk/insite/

Sad Keanu on Intranet homepage


Special bonus script for GNOME users: Python script to display sad Keanu in GTK window

Displays a sad Keanu image in a transparent GTK window that you can position where you wish. E.g.

sad_keanu_gtk example

To move him hold down Alt and then click and drag. I was going to sit him on the bottom GNOME panel, but sadly it seems windows can't be set to be above the panel, so his legs aren't visible.


November 16, 2009

Generating Freedesktop.org spec compliant thumbnails

A lot of Linux software that needs to generate thumbnails of an image uses the freedesktop.org thumbnail specification. This is good as it means if one application has already made a thumbnail of an image then another application can make use of it rather than generating it's own. I recently found myself looking for a way to generate such thumbnails.

The impetus for this was gnome-appearance-properties. This is the application which allows you to do stuff like change your wallpaper. Sadly as the number of wallpapers available increases it's usability decreases to some extent. The reason for this is that the user interface is frozen until all the wallpaper thumbnails are displayed. This in itself isn't too bad, unless you have thousands of wallpapers, but if it's combined with a lack of pre-generated thumbnails the user interface is frozen until all the thumbnails have been generated. This is annoying because if there are few hundred wallpapers available thumbnail generation can take over thirty seconds even on a decent spec machine. Thirty seconds during which the user is left looking at an unresponsive interface. There is long standing bug report regarding this, that I can't currently locate, which makes the very sensible suggestion that the thumbnails should be loaded asynchronously. Hopefully at some point someone will implement that, but in the mean time I found myself wondering whether it was possible to script the generation of thumbnails in advance.

My first thought was ImageMagick and a bash script because I'm already familiar with those. As it turns out ImageMagick comes very, very close to being able to generate such thumbnails using the -thumbnail option. I say close, because whilst it inserts both the MTime and URI information required by the freedesktop.org spec, it generates the URI incorrectly by inserting one too many slashes at the start. It creates

$ convert /usr/share/pixmaps/backgrounds/cosmos/earthrise.jpg -thumbnail 128x foo.png
$ identify -verbose foo.png | grep Thumb::URI
Thumb::URI: file:////usr/share/pixmaps/backgrounds/cosmos/earthrise.jpg

when it needs to be

 Thumb::URI: file:///usr/share/pixmaps/backgrounds/cosmos/earthrise.jpg

At time of writing this is actually fixed, but only in the svn version. If you have 6.5.7-8 or later then you should find it generates the URI properly. If you have an older version you can create the thumbnails like this:

#!/bin/bash
# makethumb - script to generate thumbnails to freedesktop.org spec
# *** Assumes GNU coreutils. ***
file=$1
saveto=~/.thumbnails/normal
tagfile=/tmp/$(basename $0)_tags
mkdir -p $saveto
thumbname=$(echo -n file://$file | md5sum| cut -d " " -f 1);
mtime=$(date +%s -r "$file")
echo "Thumb::URI={file://${file}}" >$tagfile
echo "Thumb::MTime={${mtime}}" >>$tagfile
convert -resize 128x -strip +profile "*" $file MIFF:- | cat $tagfile - | convert MIFF:- "PNG:${saveto}/${thumbname}.png"
rm -f $tagfile
$ makethumb /usr/share/pixmaps/backgrounds/cosmos/earthrise.jpg

Generating thumbnails this way is quite slow though. Using

$ find  /usr/share/pixmaps/backgrounds/ -type f -exec ~/makethumb {} \;

332 thumbnails took around 1:15 in my tests, though obviously this will vary depending on the spec of the machine. I tried using a variant of the script which generated thumbnails for all the files in a given directory, so only invoking the script once instead of multiple times. There was no significant difference in speed between the two methods though.

So I started looking for some way to use GNOME's thumbnail generation capabilities. The only example I could find of doing this used Python GTK bindings and was incomplete. I've only ever cobbled together one python script before, (that was also to use GTK bindings), but I managed to put together this

#!/usr/bin/python
# makethumb.py - script to generate thumbnails using GTK bindings

import gnome.ui
import gnomevfs
import time
import sys
import os

file=sys.argv[1]

uri=gnomevfs.get_uri_from_local_path(file)
mime=gnomevfs.get_mime_type(file)
mtime=int(time.strftime("%s",time.localtime(os.path.getmtime(file))))
thumbFactory = gnome.ui.ThumbnailFactory(gnome.ui.THUMBNAIL_SIZE_NORMAL)
if thumbFactory.can_thumbnail(uri ,mime, 0):
thumbnail=thumbFactory.generate_thumbnail(uri, mime)
if thumbnail != None:
thumbFactory.save_thumbnail(thumbnail, uri, mtime)

Using that to generate thumbnails in the same manner shown above for the bash script was about ten seconds faster. However after some experimentation I put together this (updated 15/8/11 to include suggestions from comment 2):

#!/usr/bin/python
# makethumbs.py - generates thumbnails for all files in a directory

import gnome.ui
import gnomevfs
import time
import os

dir="/usr/share/pixmaps/backgrounds/"

thumbFactory = gnome.ui.ThumbnailFactory(gnome.ui.THUMBNAIL_SIZE_NORMAL)

for subdir, dirs, files in os.walk(dir):
for file in files:
path = os.path.join(subdir, file)
uri = gnomevfs.get_uri_from_local_path(path)
mime=gnomevfs.get_mime_type(subdir+"/"+file)
mtime = int(os.path.getmtime(path))
print uri
print mtime
if thumbFactory.can_thumbnail(uri ,mime, 0):
thumbnail=thumbFactory.generate_thumbnail(uri, mime)
if thumbnail is not None:
thumbFactory.save_thumbnail(thumbnail, uri, mtime)

I found that generates 332 thumbnails in around 9 seconds. A massive difference to repeatedly invoking the makethumb.py script. I expect there are people who could provide a detailed explanation of why it's so much faster. I am not one of them.

It's also interesting to note that I've found this script generates thumbnails around three times faster than the gnome-appearance-properties creates them. Why that is I have no idea. The thumbs that result are not identical. The thumbnails generated by the Python script have the width and height of the original image embedded in them whilst the ones generated by gnome-appearance-properties do not. The ones generated by gnome-appearance-properties have a very lightly larger file size and the Channel Statistics embedded in the thumbnails are different too. However both sets of thumbnails say they were generated by GNOME::ThumbnailFactory.

Interesting as all this is, (to me anyway if it's not to you then why did you read this far?), it's all about generating thumbnails on a per-user basis. What if it was possible to have a system wide cache of per-generated thumbnails. E.g. you install a bunch of wallpapers and along with them you can install thumbnails that will be used rather than each user generating their own. The freedesktop.org thumbnail spec does cover this. So I tried creating such thumbnails. gnome-appearance-properties ignored them. When I say ignored them, I don't mean it looked at them and didn't use them, the output of strace indicates that it doesn't even look to see they exist. Which is a shame.


June 17, 2008

Firefox 3, GTK and a downside of Enterprise Linux distros.

N.B. On 6/8/09 Novell updated Firefox in SLED 10 to version 3.0.12. They packaged up newer versions of GTK etc and supplied them as packages with names like firefox3-gtk2. I guess they got tired of backporting security fixes in to Firefox 2, or it became too difficult or just impossible to do anymore.


So Firefox 3 is released today. This is a Good Thing but also highlights a downside of using an 'Enterprise' Linux distro. The Linux version of Firefox has a dependency on the GTK toolkit and Firefox 3 requires GTK 2.10 or higher. If you're using a Linux distro that has an older version of GTK then Firefox pops up a message about how it needs GTK 2.10+ then exits. Given that part of the point of Enterprise distros is that they don't change things like library versions for years at a time, (thus providing a stability lacking in distros that release a new version every 6 months or so), this leaves anyone using a version of an Enterprise distro that has GTK older than 2.10 with something of a problem if they want Firefox 3. I am one such person as my main work machine runs Novell's SUSE Linux Enterprise Desktop 10, which has GTK 2.8.

There is of course a solution. (Aside from hoping that someone will release Firefox 3 packages for the version of your distro you're using, which for an Enterprise distro seems unlikley.) Get a new version of GTK and point Firefox 3 at it. Except it may not be that simple since GTK depends on various other libraries, possibly newer versions of those libraries than a distro with a version of GTK older than 2.10 includes. Anyway, this is how I got Firefox 3 running on SLED 10. It should be useful as a guide for other distros though some adaption may be required.

Install some packages

You'll need the following packages installed: openssl-devel, libjpeg-devel, libtiff-devel, libpng-devel. The versions that are included with your distro should do. The names may be slightly different if you're not using SLED 10. Debian and Ubuntu tend to use -dev rather than -devel in package names for example. There's probably other -devel packages you'll need apart from those I've listed and which I already had installed, but you'll find out if that's the case when you try and build stuff.

Download source code for GTK and dependencies.

These are the versions I used.:

Glib - http://ftp.gnome.org/pub/gnome/sources/glib/2.16/glib-2.16.3.tar.bz2
Cairo - http://www.cairographics.org/releases/cairo-1.2.6.tar.gz
Pango - http://ftp.gnome.org/pub/GNOME/sources/pango/1.20/pango-1.20.3.tar.bz2
ATK - http://ftp.gnome.org/pub/gnome/sources/atk/1.22/atk-1.22.0.tar.bz2
GTK - http://ftp.gnome.org/pub/gnome/sources/gtk+/2.12/gtk+-2.12.10.tar.bz2

I used Cairo 1.2.6 because it's new enough that Pango 1.20.3 will use it and old enough that it didn't require me to also build pixman.

Set some environment variables

I found I had to set the following environment variables to get the build to work. Note that the paths reflect where I installed the libraries so change to where ever you decide to install stuff.

$ export PKG_CONFIG_PATH=/local/opt/lib/pkgconfig:$PKG_CONFIG_PATH
$ export LD_LIBRARY_PATH=/local/opt/lib:$LD_LIBRARY_PATH
$ export PATH=/local/opt/bin:$PATH
$ export CPPFLAGS="-I/local/opt/gtk/include"
$ export LDFLAGS="-L/local/opt/gtk/lib"

Build and install

In the order they're listed above, unpack the source code, build and install. The build command is the same for all:

$ ./configure --prefix=/local/opt && make && make install

I installed the packages in to /local/opt since obviously I want to keep it all separate to the libraries that come with SLED 10, that's somewhere non-root users can write to on my machine and not doing this as root eliminates the chance of a typo overwritting already installed libaries. You may of course find some libraries don't build because you don't have some package or other installed so you may find you have to install a -devel package and try again. Edit: If something fails to configure or build then read the errors. Look at what libraries are mentioned then see if you have the -devel packages for those libraries installed. If not install them then try again. If you get an error about cups-config not being present then install the cups-devel package. Also read the comments and see if someone else had the same problem and a solution is suggested.

Make a wrapper script to run Firefox

You'll need to run Firefox via a wrapper script. This is what I use. If you're not using SLED 10 remove or alter the MOZ_PLUGIN_DIR value as appropriate. Replace /path-to-firefox/ with where you unpacked Firefox 3 and /local/opt with where ever you installed stuff.

#!/bin/bash
export LD_LIBRARY_PATH=/local/opt/lib
export MOZ_PLUGIN_PATH=/path-to-firefox/plugins:/usr/lib/browser-plugins
/path-to-firefox/firefox

Edit: I've just realised the MOZ_PLUGIN_DIR doesn't have any effect. I could have sworn that it did. Will have to look in to that.

Edit: Sorted out how to make Firefox 3 uses plugins in /usr/lib/browser-plugins and updated wrapper script.


Search this blog

Tags

RSS2.0 Atom
Not signed in
Sign in

Powered by BlogBuilder
© MMXXIV