Systems Library / AI Capabilities / How to Build a Background Removal and Replacement System
AI Capabilities image generation

How to Build a Background Removal and Replacement System

Remove and replace image backgrounds automatically using AI.

Jay Banlasan

Jay Banlasan

The AI Systems Guy

AI background removal and replacement for product photos turns amateur shots into professional catalog images. I build these for ecommerce stores processing hundreds of product images monthly. Upload the photo, the AI removes the background, and you can place the product on any scene: white studio, lifestyle setting, or seasonal backdrop.

The whole process takes under 5 seconds per image.

What You Need Before Starting

Step 1: Remove Backgrounds

from rembg import remove
from PIL import Image
import io

def remove_bg(input_path):
    with open(input_path, "rb") as f:
        input_data = f.read()
    output_data = remove(input_data)
    return Image.open(io.BytesIO(output_data))

def batch_remove_bg(input_folder, output_folder):
    import os
    os.makedirs(output_folder, exist_ok=True)
    results = []

    for filename in os.listdir(input_folder):
        if filename.lower().endswith((".png", ".jpg", ".jpeg")):
            input_path = os.path.join(input_folder, filename)
            img = remove_bg(input_path)
            output_path = os.path.join(output_folder, f"{os.path.splitext(filename)[0]}.png")
            img.save(output_path)
            results.append(output_path)

    return results

Step 2: Place on Solid Backgrounds

def place_on_background(foreground_path, bg_color="#FFFFFF", output_size=(1080, 1080)):
    fg = Image.open(foreground_path).convert("RGBA")

    bg = Image.new("RGBA", output_size, bg_color)

    # Scale foreground to fit with padding
    max_dim = int(min(output_size) * 0.8)
    fg.thumbnail((max_dim, max_dim), Image.LANCZOS)

    # Center the product
    x = (output_size[0] - fg.width) // 2
    y = (output_size[1] - fg.height) // 2
    bg.paste(fg, (x, y), fg)

    return bg.convert("RGB")

Step 3: Generate Scene Backgrounds with AI

from openai import OpenAI

client = OpenAI()

def generate_scene_background(scene_description, size="1024x1024"):
    prompt = f"""Create a background scene for product photography.
Scene: {scene_description}
The center of the image should be clear/empty for a product to be placed there.
Professional lighting. No people. No text.
Photorealistic quality."""

    response = client.images.generate(
        model="gpt-image-1",
        prompt=prompt,
        size=size,
        quality="high"
    )
    return response.data[0].url

SCENE_PRESETS = {
    "marble": "Clean white marble countertop with soft natural light from the left",
    "wood": "Warm wooden table surface with rustic background, soft bokeh",
    "nature": "Outdoor scene with blurred green foliage, natural sunlight",
    "minimal": "Soft gradient background, studio lighting, no distractions",
}

Step 4: Composite Product onto Scene

import requests
from io import BytesIO

def composite_on_scene(product_path, scene_url, output_path):
    # Load scene
    resp = requests.get(scene_url)
    scene = Image.open(BytesIO(resp.content)).convert("RGBA")

    # Load product
    product = Image.open(product_path).convert("RGBA")

    # Scale product to fit scene
    max_dim = int(min(scene.size) * 0.6)
    product.thumbnail((max_dim, max_dim), Image.LANCZOS)

    # Center placement
    x = (scene.width - product.width) // 2
    y = (scene.height - product.height) // 2

    scene.paste(product, (x, y), product)
    scene.convert("RGB").save(output_path)
    return output_path

Step 5: Build the Processing Pipeline

def process_product_image(input_path, scenes=None):
    if scenes is None:
        scenes = ["marble", "minimal"]

    # Step 1: Remove background
    clean_product = remove_bg(input_path)
    clean_path = f"temp/{os.path.basename(input_path)}_clean.png"
    clean_product.save(clean_path)

    # Step 2: White background version
    white = place_on_background(clean_path, "#FFFFFF")
    white.save(f"output/{os.path.basename(input_path)}_white.png")

    # Step 3: Scene versions
    for scene_name in scenes:
        scene_url = generate_scene_background(SCENE_PRESETS[scene_name])
        composite_on_scene(clean_path, scene_url, f"output/{os.path.basename(input_path)}_{scene_name}.png")

    return {"processed": True, "scenes": scenes}

What to Build Next

Add shadow generation. Products placed on backgrounds without shadows look fake. Generate natural drop shadows that match the scene lighting direction for more realistic composites.

Related Reading

Want this system built for your business?

Get a free assessment. We will map every system your business needs and show you the ROI.

Get Your Free Assessment

Related Systems