AI-Powered Product Image Processing with Python and Flask
How Pixel Prep uses BiRefNet for automatic background removal and Pillow for intelligent resizing to create marketplace-ready product images.
The Problem Every E-Commerce Seller Faces
Product images make or break online sales. Every marketplace has different requirements — Amazon wants 1000x1000px white backgrounds, Shopee prefers 800x800px, eBay has its own rules. Manually processing hundreds of images across marketplaces is a soul-crushing time sink.
Pixel Prep automates this entirely using AI-powered background removal and intelligent resizing.
The Tech Stack
- Python with Flask for the web application
- BiRefNet for AI background removal
- Pillow (PIL) for image manipulation
- PostgreSQL for user accounts and usage tracking
- Stripe for subscription billing
- Railway for deployment
Background Removal with BiRefNet
BiRefNet (Bilateral Reference Network) is a state-of-the-art model for image segmentation. Unlike older approaches that struggle with fine details like hair or transparent objects, BiRefNet handles complex edges remarkably well.
Why Not Remove.bg?
Remove.bg charges $0.20-$1.00 per image via their API. For a seller processing 500 images/month, that's $100-$500 just for background removal. Running BiRefNet on our own infrastructure costs a fraction of that.
Implementation
from PIL import Image
import torch
from torchvision import transforms
def remove_background(image_path):
image = Image.open(image_path).convert('RGB')
# Preprocess for BiRefNet
transform = transforms.Compose([
transforms.Resize((1024, 1024)),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
input_tensor = transform(image).unsqueeze(0)
with torch.no_grad():
mask = model(input_tensor)
# Apply mask to original image
mask = mask.squeeze().cpu().numpy()
mask = Image.fromarray((mask * 255).astype('uint8')).resize(image.size)
result = Image.new('RGBA', image.size)
result.paste(image, mask=mask)
return result
Intelligent Resizing
Simple resizing distorts product images. Our approach:
- Remove background to isolate the product
- Calculate bounding box of the product
- Add uniform padding around the product
- Place on target canvas (white, transparent, or custom color)
- Resize to target dimensions maintaining aspect ratio
def resize_for_marketplace(image, target_size, bg_color='white', padding_pct=0.1):
# Get bounding box of non-transparent pixels
bbox = image.getbbox()
if bbox:
product = image.crop(bbox)
else:
product = image
# Calculate dimensions with padding
target_w, target_h = target_size
padding = int(min(target_w, target_h) * padding_pct)
available_w = target_w - (padding * 2)
available_h = target_h - (padding * 2)
# Scale product to fit
ratio = min(available_w / product.width, available_h / product.height)
new_size = (int(product.width * ratio), int(product.height * ratio))
product = product.resize(new_size, Image.LANCZOS)
# Center on canvas
canvas = Image.new('RGBA', target_size, bg_color)
offset_x = (target_w - new_size[0]) // 2
offset_y = (target_h - new_size[1]) // 2
canvas.paste(product, (offset_x, offset_y), product)
return canvas
Batch Processing
Sellers don't upload one image at a time. Pixel Prep accepts ZIP files containing hundreds of images and processes them in parallel:
from concurrent.futures import ThreadPoolExecutor
import zipfile
def process_batch(zip_path, settings):
results = []
with zipfile.ZipFile(zip_path) as zf:
image_files = [f for f in zf.namelist()
if f.lower().endswith(('.jpg', '.jpeg', '.png'))]
with ThreadPoolExecutor(max_workers=4) as executor:
futures = []
for filename in image_files:
with zf.open(filename) as f:
future = executor.submit(
process_single, f.read(), settings
)
futures.append((filename, future))
for filename, future in futures:
results.append((filename, future.result()))
return create_output_zip(results)
Monetization with Stripe
Pixel Prep uses a credit-based system. Users purchase credit packs via Stripe Checkout, and each image processed deducts one credit. This model works better than subscriptions for sellers with variable volumes.
Deployment Considerations
Running AI models requires more memory than typical web apps. On Railway:
- Memory: 2GB minimum for BiRefNet inference
- CPU: 2+ vCPUs recommended for batch processing
- Startup time: Model loading takes 15-30 seconds, so keep the container running
Conclusion
By combining BiRefNet with intelligent Pillow-based resizing, Pixel Prep turns hours of manual image editing into seconds of automated processing. The cost savings for sellers processing hundreds of images monthly are significant.
Related Project
PixelPrepAI-powered product image resizer and background remover for e-commerce sellers. Bulk resize, smart canvas fitting, and AI background removal with one click.