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...

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!