12 KiB
Dynamic Image Generation API
Overview
This system generates product images on-the-fly with configurable colors, hardware positions, and other options. It uses server-side image processing with PIL/Pillow to composite and recolor product images dynamically.
Setup
1. Install Dependencies
pip install -r requirements.txt
This will install:
- Flask (web framework)
- Pillow (image processing)
- Other dependencies
2. Prepare Product Images
For the COBRAI demo product:
- Save the white storm door image as
app/images/cobrai.jpg - The configuration is already in
app/data/image_configs.json
3. Create Cache Directory
The cache directory will be created automatically when the app runs:
app/cache/product_images/
API Endpoints
1. Generate Product Image
Endpoint: GET /api/product-image/<product_code>
Parameters:
color- Color name (default: 'white')- Options: white, black, bronze, sandstone
hinge- Hinge side (default: 'right')- Options: left, right
material- Material type (default: 'aluminum')- For future use
format- Return format (default: 'image')- Options: image, json
cache- Use caching (default: 'true')- Options: true, false
Examples:
Return image directly (for use in <img> tags):
GET http://localhost:8080/api/product-image/cobrai?color=black&hinge=right
GET http://localhost:8080/api/product-image/cobrai?color=bronze&hinge=left
Return JSON with base64 image:
GET http://localhost:8080/api/product-image/cobrai?color=white&hinge=right&format=json
Response (format=image): Raw PNG image file
Response (format=json):
{
"status": "success",
"productCode": "cobrai",
"color": "black",
"hinge": "left",
"material": "aluminum",
"image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
"format": "base64"
}
2. Get Product Configuration
Endpoint: GET /api/product-config/<product_code>
Returns the complete configuration for a product including available colors, colorable regions, hardware positions, etc.
Example:
GET http://localhost:8080/api/product-config/cobrai
Response:
{
"status": "success",
"productCode": "cobrai",
"config": {
"sourceImage": "images/cobrai.jpg",
"productCode": "COBRAI",
"availableColors": {
"white": {"rgb": [255, 255, 255], "name": "White"},
"black": {"rgb": [30, 30, 30], "name": "Black"},
"bronze": {"rgb": [110, 80, 50], "name": "Bronze"}
},
"colorableRegions": [...],
"hardwarePositions": {...},
"metadata": {...}
}
}
3. Clear Image Cache
Endpoint: POST /api/clear-image-cache
Clears cached images. Useful when updating source images or configurations.
Request Body (Optional):
{
"productCode": "cobrai"
}
Response:
{
"status": "success",
"message": "Cache cleared for cobrai"
}
Configuration File Format
Location: app/data/image_configs.json
Structure:
{
"product_code": {
"sourceImage": "path/to/source.jpg",
"productCode": "PRODUCT_CODE",
"description": "Product description",
"availableColors": {
"color_name": {
"rgb": [R, G, B],
"name": "Display Name"
}
},
"colorableRegions": [
{
"name": "region_identifier",
"topLeft": [x, y],
"bottomRight": [x, y],
"description": "What this region is"
}
],
"hardwarePositions": {
"handle_right": {
"x": 580,
"y": 730,
"image": "path/to/hardware.png",
"flip": false
}
},
"glassRegions": [
{
"name": "glass_area",
"topLeft": [x, y],
"bottomRight": [x, y],
"description": "Glass/screen area"
}
],
"metadata": {
"imageWidth": 720,
"imageHeight": 1450,
"defaultColor": "white",
"defaultHinge": "right"
},
"cache": {
"enabled": true,
"directory": "cache/product_images",
"maxAge": 86400
}
}
}
Key Concepts:
Colorable Regions
Define rectangular areas to be recolored. The algorithm:
- Preserves brightness/luminosity
- Applies target color
- Maintains shadows and highlights
Coordinates are [x, y] where:
topLeft: Upper-left cornerbottomRight: Lower-right corner
Hardware Positions
Define where handles, locks, etc. should be placed:
x, y: Position to place hardware imageimage: Path to hardware PNG (with transparency)flip: Whether to flip horizontally (for left hinge)
Glass Regions
Define areas that should remain unchanged (glass, screens). Currently for documentation purposes; future feature.
Frontend Integration
Option 1: Direct Image URL
<img src="/api/product-image/cobrai?color=black&hinge=left" alt="Storm Door">
Option 2: JavaScript with Base64
async function loadProductImage(productCode, color, hinge) {
const response = await fetch(
`/api/product-image/${productCode}?color=${color}&hinge=${hinge}&format=json`
);
const data = await response.json();
if (data.status === 'success') {
document.getElementById('product-img').src = data.image;
}
}
// Usage
loadProductImage('cobrai', 'black', 'left');
Option 3: Dynamic URL Switching
function updateProductImage(color, hinge) {
const img = document.getElementById('product-img');
img.src = `/api/product-image/cobrai?color=${color}&hinge=${hinge}`;
}
// On color change
document.getElementById('color-select').addEventListener('change', (e) => {
const color = e.target.value;
const hinge = document.querySelector('[name="hinge"]:checked').value;
updateProductImage(color, hinge);
});
How Image Processing Works
Color Application
- Load base image - White or neutral colored product photo
- Define regions - Specify rectangles for frame, panels, etc.
- Calculate brightness - For each pixel, determine relative brightness
- Apply target color - Colorize while preserving brightness variations
- Result - Natural-looking colored product with preserved shadows/highlights
Brightness Preservation
# For each pixel in region:
original_brightness = (r + g + b) / 3
brightness_factor = original_brightness / 255.0
new_r = target_color_r * brightness_factor
new_g = target_color_g * brightness_factor
new_b = target_color_b * brightness_factor
This maintains shadows (darker pixels stay darker) and highlights (lighter pixels stay lighter).
Hardware Application
- Load hardware PNG with transparency
- Optionally flip horizontally for left hinge
- Composite onto product image at specified position
Caching
- Generated images are cached using MD5 hash of parameters
- Cache key:
{product_code}_{color}_{hinge}_{material} - Stored as PNG in
cache/product_images/ - Subsequent requests return cached version instantly
Testing the Endpoints
Using cURL
Test basic image generation:
curl http://localhost:8080/api/product-image/cobrai?color=black > test_black.png
Test with different configurations:
curl http://localhost:8080/api/product-image/cobrai?color=bronze&hinge=left > test_bronze_left.png
Get JSON response:
curl http://localhost:8080/api/product-image/cobrai?color=white&format=json
Get configuration:
curl http://localhost:8080/api/product-config/cobrai
Clear cache:
curl -X POST http://localhost:8080/api/clear-image-cache -H "Content-Type: application/json" -d '{"productCode":"cobrai"}'
Using Browser
Simply visit:
http://localhost:8080/api/product-image/cobrai?color=black&hinge=left
Using JavaScript Fetch
// Get image as blob
fetch('/api/product-image/cobrai?color=bronze&hinge=left')
.then(response => response.blob())
.then(blob => {
const url = URL.createObjectURL(blob);
document.getElementById('img').src = url;
});
// Get as JSON
fetch('/api/product-image/cobrai?color=black&format=json')
.then(response => response.json())
.then(data => {
document.getElementById('img').src = data.image;
});
Adding New Products
Step 1: Prepare Source Image
- Photograph product in white or neutral color
- Clean background
- Good lighting
- High resolution (will be resized)
- Save as JPG in
app/images/
Step 2: Determine Regions
Open image in image editor and note pixel coordinates:
- Frame edges (left, right, top, bottom)
- Panels/kickplates
- Rails/dividers
Record as topLeft [x, y] and bottomRight [x, y]
Step 3: Add to Configuration
Add entry to image_configs.json:
{
"your_product": {
"sourceImage": "images/your_product.jpg",
"productCode": "YOUR-PRODUCT",
"availableColors": {
"white": {"rgb": [255, 255, 255], "name": "White"},
"black": {"rgb": [30, 30, 30], "name": "Black"}
},
"colorableRegions": [
{
"name": "frame",
"topLeft": [0, 0],
"bottomRight": [100, 1450]
}
],
"metadata": {
"imageWidth": 720,
"imageHeight": 1450,
"defaultColor": "white"
}
}
}
Step 4: Test
curl http://localhost:8080/api/product-image/your_product?color=black > test.png
Performance Notes
First Request
- ~100-500ms (depending on image size and region count)
- Includes image loading, processing, and caching
Cached Requests
- ~10-50ms
- Just file system read and serve
Memory Usage
- Base image kept in memory during processing
- Minimal memory footprint when served from cache
Optimization Tips
- Use caching - Enabled by default
- Smaller source images - 1000x1600px is usually sufficient
- Fewer regions - Combine adjacent areas when possible
- CDN - Serve cached images from CDN in production
Production Deployment
Recommended Setup
- Pre-generate common combinations on deploy
- CDN to serve cached images
- Redis cache instead of filesystem (optional)
- Image optimization - Use WebP format where supported
- Rate limiting on generation endpoint
Pre-generation Script
from image_generator import ProductImageGenerator
generator = ProductImageGenerator()
products = ['cobrai', 'product2']
colors = ['white', 'black', 'bronze']
hinges = ['left', 'right']
for product in products:
for color in colors:
for hinge in hinges:
img = generator.generate_product_image(product, color, hinge)
print(f'Generated: {product} {color} {hinge}')
Troubleshooting
"PIL/Pillow not installed"
pip install Pillow
"Product not found in configuration"
Check that product code in URL matches key in image_configs.json
"Could not load base image"
Verify sourceImage path in config and that file exists
Colors look wrong
Adjust RGB values in availableColors section
Regions not coloring
- Verify coordinates are within image bounds
- Check that region isn't transparent
- Ensure topLeft is actually top-left of bottomRight
Cache not working
Check that cache/product_images/ directory is writable
Future Enhancements
Planned Features
- Material textures (wood grain, brushed metal)
- Glass tinting/color
- Shadow/lighting adjustments based on color
- Multiple hardware styles
- Size variations
- Decorative glass patterns
- WebP format support
- Batch generation CLI tool
- Admin UI for region configuration
- Automatic region detection (AI/ML)
Integration Ideas
- Direct integration with product configurator
- Real-time preview as user selects options
- Download high-res configured images
- Email configured image to customer
- Social media sharing with custom image