Creating Wallpapers with Upscaled YouTube Thumbnails
Published on March 4, 2023
I often work/study with lo-fi music mixes playing in the background. Perhaps the most intriguing thing about a lo-fi mix posted on YouTube, before it is played, is the thumbnail. Unsurprisingly, there are lots of remarkable, eye-catching, anime-inspired digital paintings used as the thumbnail for these mixes. For example, I find almost all of the thumbnails in this YouTube playlist wallpaper-worthy.
So let's go ahead and hoard a bunch of thumbnails, using yt-dlp
:
yt-dlp --write-thumbnail --no-download <link to channel or playlist>
The thumbnails are most downloaded as .webp
images with 720p resoluation. Defnitely not sharp enough for a 1080p display. Let's try upscaling them using upscayl
, which is a FOSS AI Image Upscaler. Upscayl has a GUI interface, but luckily comes with a batch image processor. So let's try it out!
I let Upscayl run overnight, and it did a pretty decent job of upscaling 1280x720 to 5120x2880, which is more than sufficient even for a 4K screen. The wallpapers are looking pretty good at this point!
I wanted to experiment with setting a new wallpaper "set" everyday, with different wallpapers for daytime, evening, and night. How will the wallpapers be categorised into daytime or nighttime? One approach could be to measure the average brightness of the wallpaper (by taking the mean of the RGB pixel value of the entire image).
I quickly asked ChatGPT to do just that:
Write a Python script to measure the brightness of an image from a scale of 1 to 100 using OpenCV
Here's the script ChatGPT wrote:
#!/usr/bin/python
import cv2
import numpy as np
# Read the image
img = cv2.imread('image.png')
# Convert the image to grayscale
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Calculate the mean of the grayscale image
mean = np.mean(gray_img)
# Normalize the mean to a scale of 1 to 100
brightness = (mean/255)*100
# Print the brightness
print("The brightness of the image is:", brightness)
Based on testing the "brightness" value reported by this script for a few images that I could visually categorize, I came up with the following thresholds:
Time | Brightness |
---|---|
Daytime | >40 |
Evening | 30 - 40 |
Night | <30 |
Let's place each image in the correct subfolder.
#!/usr/bin/python
import cv2
import os
import shutil
import numpy as np
def get_brightness(image_path):
img = cv2.imread(image_path)
# Convert the image to grayscale
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Calculate the mean of the grayscale image
mean = np.mean(gray_img)
# Normalize the mean to a scale of 1 to 100
brightness = (mean/255)*100
return brightness
def move_images(folder_path):
# Move images based on their brightness
for file_name in os.listdir(folder_path):
if file_name.endswith('.png'):
file_path = os.path.join(folder_path, file_name)
brightness = get_brightness(file_path)
if brightness < 30:
dest_folder = 'night'
elif brightness < 40:
dest_folder = 'evening'
else:
dest_folder = 'day'
print(f"Moving {file_name} to '{dest_folder}' (brightness = {brightness}...")
shutil.move(file_path, os.path.join(folder_path, dest_folder, file_name))
if __name__ == '__main__':
folder_path = '/path/to/wallpapers' # Set the path to the folder containing the images
move_images(folder_path)
Finally, let's to figure out how we're going to set a new wallpaper everyday. Here's the outline for a Bash script that...
- Choose three random images as wallpapers for today (daytime, evening, and night).
- Write to a file today's date, the daytime wallpaper, the evening wallpaper, and night wallpaper filenames.
- Set the walpaper based on the current hour.
Setting a wallpaper on KDE Plasma through a single Bash command is not as straightforward as I initially thought. Nevertheless, I found this answer which worked well for me.
This is the final Bash script that will be run on every log-in, to set the wallpaper:
#!/bin/bash
WALLPAPER_DIR="/home/fahad/configuration/Wallpapers/YouTube Wallpapers" # Set the directory where the wallpapers are stored
WALLPAPER_FILE="current" # Set the file where the wallpaper filenames are stored
DATE=$(date +%Y-%m-%d) # Get today's date in the format YYYY-MM-DD
DAY_WALLPAPER=""
EVENING_WALLPAPER=""
NIGHT_WALLPAPER=""
# If the wallpaper file is outdated, delete it
if [[ -f "$WALLPAPER_FILE" && -z "$(cat $WALLPAPER_FILE | grep $DATE)" ]]; then
rm "$WALLPAPER_FILE"
fi
if [ ! -f "$WALLPAPER_FILE" ]; then
# Get three random filenames from the wallpaper directory
DAY_WALLPAPER=$(ls "$WALLPAPER_DIR"/day | shuf -n 1)
EVENING_WALLPAPER=$(ls "$WALLPAPER_DIR"/evening | shuf -n 1)
NIGHT_WALLPAPER=$(ls "$WALLPAPER_DIR"/night | shuf -n 1)
# Write the filenames to the wallpaper file
echo "$DATE" >> "$WALLPAPER_FILE"
echo "day=$DAY_WALLPAPER" >> "$WALLPAPER_FILE"
echo "evening=$EVENING_WALLPAPER" >> "$WALLPAPER_FILE"
echo "night=$NIGHT_WALLPAPER" >> "$WALLPAPER_FILE"
else
DAY_WALLPAPER=$(cat "$WALLPAPER_FILE" | grep 'day')
DAY_WALLPAPER=${DAY_WALLPAPER#*=}
EVENING_WALLPAPER=$(cat "$WALLPAPER_FILE" | grep 'evening')
EVENING_WALLPAPER=${EVENING_WALLPAPER#*=}
NIGHT_WALLPAPER=$(cat "$WALLPAPER_FILE" | grep 'night')
NIGHT_WALLPAPER=${NIGHT_WALLPAPER#*=}
fi
# Get the current hour
HOUR=$(date +%H)
# Set the wallpaper based on the current hour and the filenames read from the file
if [ $HOUR -ge 6 ] && [ $HOUR -lt 18 ]; then
echo "Setting wallpaper $DAY_WALLPAPER..."
qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript "
var allDesktops = desktops();
print (allDesktops);
for (i=0;i<allDesktops.length;i++) {{
d = allDesktops[i];
d.wallpaperPlugin = \"org.kde.image\";
d.currentConfigGroup = Array(\"Wallpaper\",
\"org.kde.image\",
\"General\");
d.writeConfig(\"Image\", \"file://$WALLPAPER_DIR/day/$DAY_WALLPAPER\")
}}
"
elif [ $HOUR -ge 18 ] && [ $HOUR -lt 23 ]; then
echo "Setting wallpaper $EVENING_WALLPAPER..."
qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript "
var allDesktops = desktops();
print (allDesktops);
for (i=0;i<allDesktops.length;i++) {{
d = allDesktops[i];
d.wallpaperPlugin = \"org.kde.image\";
d.currentConfigGroup = Array(\"Wallpaper\",
\"org.kde.image\",
\"General\");
d.writeConfig(\"Image\", \"file://$WALLPAPER_DIR/evening/$EVENING_WALLPAPER\")
}}
"
else
echo "Setting wallpaper $NIGHT_WALLPAPER..."
qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript "
var allDesktops = desktops();
print (allDesktops);
for (i=0;i<allDesktops.length;i++) {{
d = allDesktops[i];
d.wallpaperPlugin = \"org.kde.image\";
d.currentConfigGroup = Array(\"Wallpaper\",
\"org.kde.image\",
\"General\");
d.writeConfig(\"Image\", \"file://$WALLPAPER_DIR/night/$NIGHT_WALLPAPER\")
}}
"
fi
It seems to work. Yay!