Lots of people hold large collections of bitmaps on the hard disk. These could come out of digicams or scanners; they could be yours or people might be sending you these by email.
It's nice to have a tool which will randomly pluck one of these images and place it on the root window. There are quite a few programs out there which do this, but they all have limitations. This is one more, which fits my needs, and may fit yours.
FYI, chameleon and chbg are both Debian packages and are hence just one apt-get away.
At the simplest, images_rootwindow has a mechanism of plucking each image completely at random (this is the same thing that chbg does). Alternatively, images_rootwindow has an option to wander over the table of images using a 'random walk with drift'. The choice between these behaviours is controlled by a configuration variable --
my($IMAGECHOICE) = $METHOD_RANDOMWALK;
Alternatively, you can say $METHOD_RANDOM and get simple random selection.
How does METHOD_RANDOMWALK work? At the outset, images_rootwindow constructs a table of all available images (by internally running find(1)). He randomwalks in this table, choosing images to put on screen. At each step, he draws a (uniform) random integer to move ahead or behind, but on average the step length takes him forward.
In the program, there are two configuration parameters that drive this behaviour --
my($RANDOMWALK_STEPLENGTH) = 10; # A random walk with step U(-a,a)
my($RANDOMWALK_DRIFT) = 2; # Latch on so much drift on each step
If you use these values (10 and 2), then it means that at each step, he will first draw a random integer from -10 to +10, and then add 2 to it. This generates a step in the table of images.
Here is one numerical example of the numbers that come out of using the values 10 and 2 -- suppose we start from image number 444 (+9) to 453 (+4) to 457 (+8) to 465 (-6) to 459 (+1) to 460.
Many simple, logical directory structures that people use for organising pictures have the property that when find(1) traverses the table, the table comes out chronologically sorted. In this case, it's particularly convenient to have the random walk since you're getting a random walk through time.
images_rootwindow tracks the filename of the current image in the file /tmp/currentimage. This can be used for steadily pruning an image collection. From time to time, when I see a weak image, I say --
$ rm `cat /tmp/currentimage`
This is effective at killing low quality images. It is not effective at dealing with duplicates.
WARNING: This makes sense for people like me, where I live on a notebook where I'm the only user. On a multiuser machine, you generally don't want the whole world to know names of your files. I take care to make /tmp/currentimage have perms of 0400 but this is a risk.
Progress: In March 2002, I had submitted a feature request for `chbg', through the Debian bug tracking system, suggesting that this feature should be added in. Today (18/2/2004) they told me that this has been done. Jochen Voss warned me that he applied the patch to the Debian version of chbg, and sent it to Stefan (the upstream author), where it awaits inclusion into the code. Hence, for this one issue, you no longer need images_rootwindow.pl.
Sometimes you have nothing to do and only want to gaze at the images, and you want to push him on to the next image. images_rootwindow makes this possible (in a certain twisted fashion).
First, images_rootwindow uses an external sleep(1) process to implement the delay from one image to the next. So if you can find that sleep process and kill it, you will get the next image.
This can get slightly confusing when there are multiple sleep processes in core. What if you do 'ps xa | grep sleep' and there are many different sleep processes going on? So images_rootwindow is kind enough to always express his sleep duration as a real number of days. This is so non-standard that it leaps out at you.
Example --
$ ps xa | grep sleep 25896 pts/0 S 0:00 sleep 0.00526187316621384d 25899 pts/0 S 0:00 sleep 10 25901 pts/0 S 0:00 grep sleep
So when you glance at this, you just know that it is 25896 that you have to kill, in order to get the next image. I know, this is a bit geeky, but it's really easy to use once you think about it.
I have this:
alias nextpic='ps xa | grep '\''sleep.*d$'\'' | awk '\''{print $1}'\'' | xargs kill'
So I say `nextpic' to urge him on to the next picture.
images_rootwindow knows nothing about pixels. When display has to be done, it fires a command that you can define. Inside images_rootwindow is a configuration variable called displayprogram. You can put any string there that you like and it will be utilised for display. So if you are happy with the rootwindow that is produced by saying:
$ foobar -a -b -c file.jpg
then you would set --
my($displayprogram) = 'foobar -a -b -c';
One choice that works (with limitations) is chameleon --
my($displayprogram) = 'chameleon';
This has problems since he doesn't preserve aspect ratio, he does not know how to have a black border, etc. Another choice is --
my($displayprogram) = 'xv -root -rmode 5 -quit';
which is troublesome because xv is unfree. I use --
my($displayprogram) = 'chbg -ypos 0.25 -effect 1 -mode smart -once';
where I'm using chbg -once to do the work of just placing one image on rootwindow and walking away. The -ypos is used to push the image a little higher (vertically) as compared with the default, in order to make space for the toolbar which the window manager shows at the bottom.
You have to open the file images_rootwindow.pl and edit a few lines. The relevant paragraph looks like this --
# START OF CONFIGURATION PARAMETERS
# Global options
my($verbose) = 1;
# Options controlling creation of list of images
my(@extensions) = qw(jpg JPG);
my(@directories) = qw(/home/ajayshah/GAMES/IMAGES);
my($minsize) = '100k';
# Options controlling image randomisation
my($IMAGECHOICE) = $METHOD_RANDOMWALK;
my($RANDOMWALK_STEPLENGTH) = 10; # A random walk with step U(-a,a)
my($RANDOMWALK_DRIFT) = 2; # Latch on so much drift on each step
# Options controlling display
my($trackerfile) = '/tmp/currentimage';
my($displayprogram) = 'chbg -ypos 0.25 -effect 1 -mode smart -once';
my($A, $B) = (100, 500); # Inter-image delay U(a,b)
# END OF CONFIGURATION PARAMETERS
At the simplest, you can just say --
$ images_rootwindow.pl > /dev/null
It daemonifies. I like to have it run every time X starts. So I have the following line in my $HOME/.xsession file --
nice -19 ~/BIN/images_rootwindow.pl > /dev/null
When you are experimenting with images_rootwindow, it's useful to kill the sleep process, which forces him to go on to the next images. The sleep process used by images_rootwindow is sharply identifiable in the output of `ps' since it talks about a real-valued number of days. You may find this convenient --
$ ps xa | grep '0\.[0-9]*d$' | awk '{print $1}' | xargs kill
I sometimes do the following in order to get a high speed slideshow --
$ while [ 1 ] ; do
ps xa | grep '0\.[0-9]*d$' | awk '{print $1}' | xargs kill
sleep 10
done
find to
gfind.
sleep
0.00005d and see if it works. Once again, on many systems,
gsleep may be the goods you need.