🎨 Build a Background Generator Tool in Python (Step-by-Step)

Published: (January 19, 2026 at 04:13 AM EST)
4 min read
Source: Dev.to

Source: Dev.to

Tools & Libraries

LibraryPurpose
Tkinter + ttkbootstrapModern GUI with dark/light themes
Pillow (PIL)Image creation & manipulation
NumPyFast pixel‑level noise generation
random & timeRandomness & timestamped filenames

👉 Final project (GitHub):

📌 What You’ll Learn

  • How to generate gradients programmatically
  • How to add noise & texture to images
  • How to build a modern Tkinter GUI
  • How to resize images for live previews
  • How to export images with smart filenames

🧰 Step 1 – Install Required Libraries

pip install ttkbootstrap pillow numpy

Why these libraries?

  • ttkbootstrap – modern dark/light themes for Tkinter
  • Pillow – image creation & manipulation
  • NumPy – fast pixel‑level noise generation

📦 Step 2 – Import the Required Modules

import ttkbootstrap as tb
from ttkbootstrap.constants import *
from tkinter import filedialog, messagebox
from tkinter import ttk
from PIL import Image, ImageDraw, ImageFilter, ImageTk
import numpy as np
import random
import time

🔹 This setup prepares GUI elements, image processing, and utility tools.

🎛 Step 3 – Add Noise to an Image

def add_noise(img, intensity=10):
    arr = np.array(img)
    noise = np.random.randint(-intensity, intensity + 1, arr.shape, "int16")
    noisy = np.clip(arr + noise, 0, 255).astype("uint8")
    return Image.fromarray(noisy)

🧠 What’s happening?

  1. Convert the image to a NumPy array
  2. Add random pixel values
  3. Clamp values between 0 – 255
  4. Convert back to a PIL image

🌈 Step 4 – Generate a Vertical Gradient

def generate_gradient(size):
    w, h = size
    top_color = (
        random.randint(50, 255),
        random.randint(50, 255),
        random.randint(50, 255)
    )
    bottom_color = (
        random.randint(50, 255),
        random.randint(50, 255),
        random.randint(50, 255)
    )

    img = Image.new("RGB", size)
    draw = ImageDraw.Draw(img)

    for y in range(h):
        r = int(top_color[0] + (bottom_color[0] - top_color[0]) * y / h)
        g = int(top_color[1] + (bottom_color[1] - top_color[1]) * y / h)
        b = int(top_color[2] + (bottom_color[2] - top_color[2]) * y / h)
        draw.line((0, y, w, y), fill=(r, g, b))

    return add_noise(img, intensity=5)

🎨 Explanation: Each row interpolates color values from topbottom.

✨ Step 5 – Create a Texture Overlay

def generate_texture(size):
    img = Image.new("RGBA", size)
    draw = ImageDraw.Draw(img)

    for _ in range(size[0] * size[1] // 50):
        x = random.randint(0, size[0] - 1)
        y = random.randint(0, size[1] - 1)
        color = (
            random.randint(100, 255),
            random.randint(100, 255),
            random.randint(100, 255),
            random.randint(20, 50)
        )
        draw.point((x, y), fill=color)

    return img

🔹 This randomly scatters semi‑transparent pixels across the image.

🧩 Step 6 – Combine Gradient + Texture

def generate_background(size):
    base = generate_gradient(size)
    texture = generate_texture(size)
    base.paste(texture, (0, 0), texture)
    return base

✔ Gradient ✔ Noise ✔ Texture ✔ Final image

🖥 Step 7 – Create the Main App Window

class BackgroundGenerator:
    def __init__(self, root):
        self.root = root
        root.title("Background Generator Tool")
        root.geometry("1200x700")
        root.resizable(True, True)

This sets the window title, size, and resizability.

📐 Step 8 – Define Export Resolutions

self.resolutions = {
    "HD (1280x720)": (1280, 720),
    "Full HD (1920x1080)": (1920, 1080),
    "2K (2560x1440)": (2560, 1440),
    "4K (3840x2160)": (3840, 2160),
    "Ultra HD (6000x3375)": (6000, 3375)
}

Users can choose professional‑grade sizes with one click.

🎚 Step 9 – Build the Control Panel (Left Side)

left = tb.Frame(root, width=300, bootstyle="secondary")
left.pack(side="left", fill="y", padx=10, pady=10)

Orientation Selector

self.orient_combo = ttk.Combobox(
    left, values=["Landscape", "Portrait"], state="readonly"
)
self.orient_combo.current(0)
self.orient_combo.pack(fill=X)

Resolution Selector

self.res_var = tb.StringVar(value="Full HD (1920x1080)")
tb.OptionMenu(left, self.res_var, *self.resolutions.keys()).pack(fill=X)

🖼 Step 10 – Live Preview Canvas

self.canvas = tb.Canvas(root, bg="black", highlightthickness=0)
self.canvas.pack(expand=True, fill="both")

This displays a scaled preview of the generated background.

🔄 Step 11 – Generate & Resize the Preview

def update_preview(self):
    img = self.state["bg"].copy()
    canvas_w = self.canvas.winfo_width()
    canvas_h = self.canvas.winfo_height()

    if canvas_w > 0 and canvas_h > 0:
        ratio = min(canvas_w / img.width, canvas_h / img.height)
        preview = img.resize(
            (int(img.width * ratio), int(img.height * ratio)),
            Image.ANTIALIAS
        )
        self.tk_img = ImageTk.PhotoImage(preview)
        self.canvas.create_image(
            canvas_w // 2, canvas_h // 2,
            image=self.tk_img, anchor="center"
        )

The method keeps the preview proportional to the canvas size.

🖼️ Step 11 (Alternative) – Display the Preview

ratio = min(canvas_w / img.width, canvas_h / img.height)
new_size = (int(img.width * ratio), int(img.height * ratio))
preview = img.resize(new_size)

self.tk_img = ImageTk.PhotoImage(preview)
self.canvas.delete("all")
self.canvas.create_image(
    canvas_w // 2, canvas_h // 2, image=self.tk_img
)

🧠 Keeps the image centered & scaled properly.

💾 Step 12 – Export the Background

def save_bg(self):
    w, h = self.state["size"]
    timestamp = int(time.time())
    filename = f"background_{w}x{h}_{timestamp}.png"

    f = filedialog.asksaveasfilename(
        initialfile=filename,
        defaultextension=".png",
        filetypes=[("PNG Image", "*.png"), ("JPEG Image", "*.jpg")]
    )

    if f:
        self.state["bg"].save(f)
        messagebox.showinfo("Success", "Background saved!")

✔ Automatic filenames
✔ PNG or JPG support

🚀 Running the App

if __name__ == "__main__":
    root = tb.Window(themename="darkly")   # or "flatly" for a light theme
    app = BackgroundGenerator(root)
    root.mainloop()

Now you have a fully functional background‑generator GUI that lets you:

  • Choose orientation (landscape/portrait)
  • Pick a resolution from the predefined list
  • See a live preview that updates instantly
  • Export the final image with a timestamped filename

Enjoy creating beautiful, random backgrounds for your projects!

🚀 Final Thoughts

This project is perfect if you want to:

  • Practice image processing
  • Learn Tkinter GUI development
  • Build creative Python tools

🔗 Source Code:
https://github.com/rogers-cyber/python-tiny-tools/tree/main/Background_Generator_Tool

If you enjoyed this tutorial, consider ⭐ starring the repo and sharing it on Dev.to!

Happy coding 👨‍💻🎨

Background Generator Demo

Back to Blog

Related posts

Read more »