*** For multiple monitors see this post instead
Set windows wallpaper from python for multiple monitors ***
Here's some code to set a random wallpaper from a list of images, or a list of directories or a single image. It doesn't recurse subdirectories, but, that's just as simple to add if you really require that functionality. It requires PIL.
You can set it to change the wallpaper to rotate to a new one at a specified number of minutes.
It can use any image that PIL can read (it converts it to a BMP).
import os
import time
import random
from optparse import OptionParser
from ConfigParser import SafeConfigParser
from ctypes import windll
from win32con import *
from PIL import Image
"""
I recommend you create a pywallpaper.conf file that looks something like this;
[directories]
paths = C:\Documents and Settings\akm\My Documents\My Pictures\gb
C:\Documents and Settings\akm\My Documents\My Pictures\Ralph
to store the directories in rather than specifying -d multiple times on the command line"""
def getDefaultDirs():
return [r'C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures',]
def setWallPaperFromBmp(pathToBmp):
result = windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0,
pathToBmp,
SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE)
if not result:
raise Exception("Unable to set wallpaper.")
def setWallPaper(pathToImage):
bmpImage = Image.open(pathToImage)
newPath = os.getcwd()
newPath = os.path.join(newPath, 'pywallpaper.bmp')
bmpImage.save(newPath, "BMP")
setWallPaperFromBmp(newPath)
def setWallPaperFromFileList(pathToDir):
tries = 0
done = False
while (not done) and tries < 3:
try:
files = os.listdir(pathToDir)
image = random.choice(files)
setWallPaper(os.path.join(pathToDir, image))
done = True
except:
tries += 1
return done
def setWallPaperFromDirList(pathList):
imageDir = random.choice(pathList)
status = setWallPaperFromFileList(imageDir)
def getImageDirectories(options):
configFile = 'pywallpaper.conf'
if options.configFile:
configFile = options.configFile
dirs = options.directories
try:
config = SafeConfigParser()
config.readfp(open(configFile))
dirs += config.get('directories', 'paths').split('\n')
except:
pass
if not dirs:
dirs = getDefaultDirs()
return dirs
def setWallPaperFromConfigDirs(options):
setWallPaperFromDirList(getImageDirectories(options))
def getCommandLineOptions():
parser = OptionParser()
parser.add_option("-t", "--time", dest="change_time",
help = "Change wallpaper time in minutes (0 = change once and exit [default])",
default = 0, type = "int")
parser.add_option("-i", "--image", dest="singleImage", default = None,
help = "Set wallpaper to this image and exit (overrides -d)")
parser.add_option("-d", "--directory", dest="directories", default = [],
action="append", type="string",
help = "Add an image directory")
parser.add_option("-c", "--config", dest="configFile", default = None,
help = "path to alternate config file (default <working dir>/pywallpaper.conf)")
parser.add_option("-w", "--workingdir", dest="cwd", default=".",
help = "Working Directory (default .)")
(options, args) = parser.parse_args()
return (options, args)
if __name__ == '__main__':
options, args = getCommandLineOptions()
if options.cwd and options.cwd != '.':
os.cwd(cwd)
if options.singleImage:
setWallPaper(options.singleImage)
elif not options.change_time:
setWallPaperFromConfigDirs(options)
else:
dirs = getImageDirectories(options)
sleepTime = options.change_time * 60.0
while True:
setWallPaperFromDirList(dirs)
time.sleep(sleepTime)