Skip to content

Instantly share code, notes, and snippets.

@Alexandro1112
Forked from ssssssssk/Mac-bg.py
Created March 6, 2023 18:23
Show Gist options
  • Save Alexandro1112/c358de549aecc2893e782c03efe92adb to your computer and use it in GitHub Desktop.
Save Alexandro1112/c358de549aecc2893e782c03efe92adb to your computer and use it in GitHub Desktop.
#!/Users/steve/.pyenv/shims/python
# Thing to make new desktop backgrounds from my folder of research images
# On Linux I made this actually write to the desktop directly using feh, however, that's not really possible on a Mac. So I had it create a folder of graphics and then have the desktop settings choose from that directory at random.
from PIL import Image, ImageDraw
import os, random
from subprocess import call
## Colors from the Nord color scheme,
# colors = ['#D8DEE9', '#D8DEE9', '#D8DEE9', '#D8DEE9', '#D8DEE9', '#D8DEE9', '#E5E9F0', '#81A1C1', '#BF616A', '#EBCB8B']
## Colors from Oceanic Next Color Scheme
colors = ['#C0C5CE', '#CDD3DE', '#D8DEE9', '#EC5f67', '#F99157', '#FAC863', '#99C794', '#5FB3B3', '#6699CC', '#C594C5']
## Laptop Screen Dims
screenW = 1440
screenH = 900
## Desktop Screen Dims
# screenW = 1680
# screenH = 1050
## Where the files come from and where the files go.
image_dir = "/Users/steve/Syncables/PICJAIL"
out_dir = "/Users/steve/Pictures/BGDUMP/"
count = 0
## Filter the files to make sure you only get images, no DS Store or whatever
pic_extensions = ['.jpg', '.JPG', '.jpeg', '.JPEG', '.png', '.PNG']
Pix = [f for f in os.listdir(image_dir)
if any(f.endswith(ext) for ext in pic_extensions)]
## Establish some dimensions based on screen size for use later.
baseheight = int(screenH / 2)
top_offset = (int((screenH / 2) - (baseheight / 2)))
## Create a class for pictures to avoid having to keep grabbing random pictures the hard way.
class picture:
def __init__(self):
image_choice = random.choice(Pix)
the_picture = Image.open(f"{image_dir}/{image_choice}")
self.w = the_picture.width
self.h = the_picture.height
self.pic = the_picture
def thumb(self, dimensions):
self.pic.thumbnail(dimensions)
self.w = self.pic.width
self.h = self.pic.height
## This function creates a background using a flood of a random color then puts however many random images the 'times' variable tells it to put on the screen.
def makeBG(count, times):
# divide the screen into n equal parts
max_width = int(screenW / times)
# center the image on the screen
max_height = screenH - 70
i = count
bg_color_field = Image.new('RGB', (screenW, screenH), (random.choice(colors)))
img_draw = ImageDraw.Draw(bg_color_field)
# Create an object from the picture class. Iterate through as many times as necessary
for n in range(times):
p1 = picture()
p1.thumb((max_width + (random.randint(1, 20) * (p1.w / 144)), max_height))
pic_1_pos_w = int(max_width / 2) - int(p1.w / 2) + (max_width * (times - 1))
pic_1_pos_h = int(screenH / 2) - int(p1.h / 2)
bg_color_field.paste(p1.pic, (pic_1_pos_w, pic_1_pos_h))
times = times - 1
bg_color_field.save(out_dir + str(i) + "-bg.png")
## This function crops an image to cover the entire screen, then places a colored block in that space, then places an image in that same colored block.
def floodBG(count):
i = count
bg_color_field = Image.new('RGB', (screenW, screenH), (random.choice(colors)))
img_draw = ImageDraw.Draw(bg_color_field)
while True:
p1 = picture()
width, height = p1.pic.size
# make sure to get a picture that is big enough to be cropped to desktop size
if (width > screenW and
height > screenH):
cW = ((width - screenW) / 2)
cH = ((height - screenH) / 2)
cropped = p1.pic.crop((cW, cH, width - cW, height - cH))
bg_color_field.paste(cropped, (0, 0))
# create rectangle size and position
wSize = ((int(random.randint(100, (screenW)))), (int(random.randint(200, (screenH)))))
wPos = ((int(wSize[0] / 2)), (int(wSize[1] / 2)))
# rectangle is produced and color selected
wrecked = Image.new('RGB', (wSize), (random.choice(colors)))
bg_color_field.paste(wrecked, wPos)
## Make a random picture appear inside the first colored box
p2 = picture()
p2.thumb(wSize)
bg_color_field.paste(p2.pic, wPos)
break
bg_color_field.save(out_dir + str(i) + "-bg.png")
## This function creates a colored background, then selects 'times' number of pictures, makes them the same height, centers them in the middle and puts a 'drop shadow' under them.
def centerJoin(count, times):
i = count
bg_color_field = Image.new('RGB', (screenW, screenH), (random.choice(colors)))
img_draw = ImageDraw.Draw(bg_color_field)
# create a list to hold the two or more images in.
d = {}
while True:
# create a dictionary to retrieve image sizes of different iterations
dw = []
for n in range(times):
holder = picture()
hpercent = (baseheight / float(holder.h))
wsize = int((float(holder.w) * float(hpercent)))
holder.pic = holder.pic.resize((wsize, baseheight))
dw.append(holder.pic.size[0])
d[f"p{n}"] = holder.pic
image_length = sum(dw)
#In practice it's very difficult for a series of random images to match these criteria if you select more than 2 images. At 3 it takes a long time to complete.
if image_length < float(screenW * 0.7):
side_offset = int((screenW - image_length) / 2)
# create the drop shadow and paste it on there.
drop_shadow = Image.new('RGB', (image_length, baseheight), (random.choice(colors)))
bg_color_field.paste(drop_shadow, ((side_offset + 20), (top_offset + 20)))
w_track = side_offset + image_length
#this was the hardest part for me.
## iterating through the two different images and pasting them on at the right place, based on their widths, entirely programatically, without assigning variables.
for i in range(len(dw)):
position = (w_track - dw[i], top_offset)
bg_color_field.paste(d[f"p{i}"], position)
i = i - 1
w_track = w_track - dw[(i + 1)]
break
bg_color_field.save(out_dir + str(i) + "-bg.png")
## In effect, that last one could have been done with just creating two objects -- there was no need to iterate through the lists and dicts really, since finding 3 images that meet the criteria is hard. Might even be clearer if that didn't happen.
# Controls the way each function is applied.
while count < 30:
if count == int(1):
centerJoin(count, 2)
elif (count % 3) == 0:
floodBG(count)
else:
makeBG(count, random.randint(2, 4))
count = count + 1
# MacOS is then directed to select desktop backgrounds randomly from the BGDUMP folder every five minutes. Cron runs the script every couple hours to refresh the desktops available.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment