In this tutorial, we’ll build a Python GUI app that generates random gradient + texture backgrounds, lets users preview them live, choose orientation & resolution, and export the final image.
We’ll use:
Tkinter + ttkbootstrap → modern GUI
Pillow (PIL) → image processing
NumPy → noise generation
Random & Time → randomness + filenames
👉 Final project (GitHub):
https://github.com/rogers-cyber/python-tiny-tools/tree/main/Background_Generator_Tool
📌 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
Before coding, install the dependencies:
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
Start by importing everything we’ll need.
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
Noise gives our backgrounds a more natural & textured look.
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 here?
Convert the image to a NumPy array
Add random pixel values
Clamp values between 0–255
Convert back to a PIL image
🌈 Step 4: Generate a Vertical Gradient
Now we generate a smooth color 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)
🎨 Each row interpolates color values from top → bottom.
✨ Step 5: Create a Texture Overlay
Textures add depth and visual interest.
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
Now we merge everything into one final background.
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
Let’s initialize the GUI 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)
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
▶ Step 13: Run the App
if __name__ == "__main__":
root = tb.Window(themename="darkly")
app = BackgroundGenerator(root)
root.mainloop()
🎉 That’s it! You now have a fully functional background generator app.
🚀 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 👨💻🎨
