"wallfix", using python to set my wallpaper
I had fun writing about my "cd" helper, so I thought I'd share another productivity helper I wrote for setting my wallpaper. It's a little silly, but I insist on my wallpaper being used for my lockscreen and my login window as well -- that way the entire time I'm on my computer the background is "seamless". Before I wrote this script it used to take me probably 3 or 4 minutes to change wallpapers!
I use the following utilities on my desktop, so I needed a way to set the background for all of them:
Due to some quirks in the way all these tools work, I found that in order for
my computer to always display the exact same background I needed to resize
the image to be exactly the size of my desktop. This was additionally
complicated by the fact that wallpapers come in different aspect ratios, so
sometimes I would have to crop things as well. Lastly, for whatever reason,
SLiM wants a
.jpg while i3lock only takes a
I needed to write a helper that would:
- Resize and crop the image to fit my screen size.
- Generate a .png and a .jpg
- Tell i3lock, SLiM and my desktop (
feh) to use the right image.
Symlinks to the rescue
The first step was I established
as the canonical location of my wallpaper images. I then updated SLiM, i3lock and
feh to point at those images. Doing this means that I only need to write the
images to once place and everything will just work!
Resizing and cropping
I wrote this script with python and used PIL to do the image manipulation. Here is the entire script:
#!/usr/bin/env python import os import sys from PIL import Image HOME = os.environ['HOME'] WIDTH = 1440 HEIGHT = 900 RATIO = float(WIDTH) / HEIGHT def local_file(filename): return os.path.join(HOME, filename) def make_wallpapers(original): im = Image.open(original) width, height = im.size ratio = float(width) / height if ratio > RATIO: # resize to match height, then crop horizontally from center new_width = int(HEIGHT * ratio) im.thumbnail((new_width, HEIGHT), Image.ANTIALIAS) offset = (new_width - WIDTH) / 2 cropped = im.crop((offset, 0, offset + WIDTH, HEIGHT)) elif ratio < RATIO: # resize to match width, then crop vertically from center new_height = int(WIDTH / ratio) im.thumbnail((WIDTH, new_height), Image.ANTIALIAS) offset = (new_height - HEIGHT) / 2 cropped = im.crop((0, offset, WIDTH, offset + HEIGHT)) else: im.thumbnail((WIDTH, HEIGHT), Image.ANTIALIAS) cropped = im path, ext = os.path.splitext(original) dest_jpg = local_file('.wallpaper.jpg') dest_png = local_file('.wallpaper.png') cropped.save(dest_jpg, 'JPEG', quality=100) cropped.save(dest_png, 'PNG') if __name__ == '__main__': if len(sys.argv) == 1: filename = raw_input('New image? ') else: filename = sys.argv[-1] if not os.path.exists(filename): print 'Error: %s not found' % filename sys.exit(1) make_wallpapers(filename)
To use this, I just run
wallfix ~/pictures/Wallpapers/kittens3.jpg and
everything is set up!
The moral of the story
I think I spent 30 minutes setting this all up. If the amount of time it used to take me to change my wallpaper manually was 3 minutes, after 10 changes I'll have made up the time. More than the time saved, though, I think it's useful to be mindful of tasks you do that are repetitive and figure out how to automate them.
Commenting has been closed, but please feel free to contact me