Created
February 5, 2021 20:35
-
-
Save ssssssssk/41542aa0e7b55984963a76ecfd2d2dc1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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