#!/usr/bin/perl
#
# random_wallpaper.pl
#
# Copyright (C) 2009 Nathan Shafer
#
# This program is free software; you can redistribute it and/or *
# modify it under the terms of the GNU General Public License *
# as published by the Free Software Foundation; either version 2 *
# of the License, or (at your option) any later version. *
# *
# This program is distributed in the hope that it will be useful, *
# but WITHOUT ANY WARRANTY; without even the implied warranty of *
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# GNU General Public License for more details. *
# *
# You should have received a copy of the GNU General Public License *
# along with this program; if not, write to the Free Software *
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*
#
# ------------------------------------------------------------------------------
# Description
# ------------------------------------------------------------------------------
# This script will randomly change Gnome's wallpaper. It supports a single
# monitor or multiple monitors by stitching together different wallpapers for
# each screen. Simply configure a few options below then run this script.
#
# Here are a few notes for multiple monitors:
# - The monitors can be stacked vertically or set up horizontally side by side,
# but no other physical setups are supported. The reason is that we're
# creating one big image to make this work, so the image has to be a rectangle.
# So for example, with 2 monitors of 1600x1200, the script creates an image
# that is 3200x1200 in size for a horizontal layout. A vertical layout would
# create 1600x2400.
# - If you have mismatched resolution sizes, we will create the image based on
# the smallest resolution of the monitors. So for example, a 1600x1200 next
# to a 1024x768 will result in an image of (horizontally) 2048x768. I don't
# know what will happen if it creates the image at the max resolution of the
# monitors... I don't have mismatched resolutions. If someone wants to test
# the two options and tell me which is better, I would appreciate it.
#
# ------------------------------------------------------------------------------
# Requirements
# ------------------------------------------------------------------------------
# This script was developed and tested on linux. Other OSes will probably work
#
# It requires Perl of course.
#
# It also only works with Gnome
#
# This script requires you have PerlMagick installed. This can be installed
# from CPAN, but on debian based linux distros, you can install it with
# sudo apt-get install perlmagick
# and on redhat based linux distros, this should work:
# sudo yum install ImageMagick-perl
#
# ------------------------------------------------------------------------------
# Installation
# ------------------------------------------------------------------------------
# Simply put the script somewhere and execute it.
#
# This script works really well as a startup item to change your wallpaper
# every time you log in, or as a cron to change it on a set schedule. For
# example, edit your crontab with "crontab -e" and put this in it:
#
# */30 * * * * /path/to/random_wallpaper.pl
#
# That will change it every 30 minutes. Change the 30 to whatever interval you want
#
use strict;
use Image::Magick;
use vars qw($x);
################################################################################
# OPTIONS
################################################################################
# This is an array of arrays, each being the dimensions of each of your
# monitors. List each monitor's resolution on its own line like the example
# below. You can have as many screens listed as you want, as long as they are
# all in a straight line. So either all horizontal or all vertical.
my @screens = (
['1600', '1200'], # Left monitor
['1600', '1200'], # Right monitor
);
# Specify the orientation of your monitors as either "horizontal" or "vertical"
my $orientation = "horizontal";
# Add the full path to each directory you want to pull images from randomly
my @wallpaper_dirs = (
'/home/nicodemus/wallpapers',
);
# Specify the file to output the final image to
my $output_file = "/tmp/change_wallpaper_output.jpg";
# Turn debugging on or off with either 1 or 0
my $debug = 0;
################################################################################
# END CONFIG - DO NOT EDIT ANYTHING BEYOND THIS UNLESS YOU KNOW WHAT YOU'RE DOING
################################################################################
# Load the list of possible wallpapers into memory
my @wallpapers;
foreach my $dir (@wallpaper_dirs) {
opendir(DIR, $dir) or die("Could not open directory $dir: $!\n");
while(my $file = readdir DIR) {
next if $file =~ /^\./;
if($file =~ /.jpg|.jpeg|.png|.bmp$/i) {
push(@wallpapers, "$dir/$file");
} else {
print "invalid file in $dir: $file\n" if $debug;
}
}
}
# Fetch a random wallpaper for each screen
my @selected_wallpapers;
foreach (@screens) {
push(@selected_wallpapers, $wallpapers[int(rand(@wallpapers))]);
}
print "selected: @selected_wallpapers\n" if $debug;
# figure out our target tile orientation and minimum screen size
my $rows = 0;
my $columns = 0;
my $tile_width = 1_000_000;
my $tile_height = 1_000_000;
foreach my $screen (@screens) {
if($orientation eq 'vertical') {
$columns = 1;
$rows++;
} else {
$columns++;
$rows = 1;
}
if($screen->[0] < $tile_width || $screen->[1] < $tile_height) {
$tile_width = $screen->[0];
$tile_height = $screen->[1];
}
}
print "Target layout: $rows x $columns\n" if $debug;
# Now load the selected wallpapers
my $input = new Image::Magick();
$x = $input->Read(@selected_wallpapers);
warn($x) if $x;
# Get the size of the input images
for ($x = 0; $input->[$x]; $x++) {
print "image $x geometry: " . $input->[$x]->Get('width') . 'x' . $input->[$x]->Get('height') . "\n" if $debug;
}
# Create the output file as a "Montage" of the input files
my $output = $input->Montage(geometry=>"${tile_width}x${tile_height}", background=>"black", tile=>"${columns}x${rows}");
# Get the output geometry
print "Output geometry: " . $output->Get('width') . 'x' . $output->Get('height') . "\n" if $debug;
# Write it
$x = $output->Write($output_file);
warn($x) if $x;
# Now tell Gnome to change the wallpaper
system("/usr/bin/gconftool-2 --type string --set /desktop/gnome/background/picture_filename $output_file");