Generator Module
The generator
module provides functionality for creating embedded image resources and generating Python code for image distribution.
Image embedding generator for gui_image_studio package.
- gui_image_studio.generator.embed_images_from_folder(folder_path, output_file='embedded_images.py', compression_quality=85)[source]
Processes all valid images in a folder, applies optional JPEG/WebP compression, categorizes them by theme (if the filename starts with a theme followed by an underscore), and writes them into an output Python file.
- gui_image_studio.generator.generate_embedded_images()[source]
Console script entry point for generating embedded images.
Overview
The generator module allows you to:
Convert images to base64-encoded strings
Generate Python modules with embedded images
Create optimized image resources for distribution
Batch process image folders
This is particularly useful for:
Distributing applications with embedded icons
Creating self-contained packages
Reducing external dependencies
Improving application startup time
Main Functions
embed_images_from_folder
- gui_image_studio.generator.embed_images_from_folder(folder_path, output_file='embedded_images.py', compression_quality=85)[source]
Processes all valid images in a folder, applies optional JPEG/WebP compression, categorizes them by theme (if the filename starts with a theme followed by an underscore), and writes them into an output Python file.
The main function for generating embedded image resources from a folder.
Basic Usage:
from gui_image_studio import embed_images_from_folder
# Generate embedded images from a folder
embed_images_from_folder(
folder_path="assets/icons",
output_file="embedded_icons.py",
compression_quality=85
)
Parameters:
folder_path
(str): Path to the folder containing imagesoutput_file
(str): Name of the generated Python file (default: “embedded_images.py”)compression_quality
(int): JPEG/WebP quality 1-100 (default: 85)
Methods:
generate
Generate the embedded images Python module.
- Returns:
bool
: True if generation was successful
Example:
success = generator.generate()
if success:
print("Resources generated successfully")
else:
print("Generation failed")
add_image
Add a single image to the generator.
- Parameters:
image_path
(str): Path to the image filename
(str, optional): Name for the embedded image (defaults to filename)
Example:
generator.add_image("icon.png", "main_icon")
generator.add_image("logo.jpg") # Uses "logo" as name
remove_image
Remove an image from the generator.
- Parameters:
name
(str): Name of the image to remove
Example:
generator.remove_image("unwanted_icon")
list_images
List all images currently in the generator.
- Returns:
List[str]
: List of image names
Example:
images = generator.list_images()
print(f"Images to embed: {', '.join(images)}")
set_compression
Configure image compression settings.
- Parameters:
compress
(bool): Enable compressionquality
(int): JPEG quality (1-100)max_size
(Tuple[int, int], optional): Maximum image size
Example:
generator.set_compression(True, quality=75, max_size=(256, 256))
Utility Functions
encode_image
Encode a single image to base64 string.
- Parameters:
image_path
(str): Path to the image fileformat
(str, optional): Output format (‘base64’ or ‘bytes’)compress
(bool, optional): Apply compressionquality
(int, optional): JPEG quality for compression
- Returns:
str
: Encoded image data
Example:
encoded = encode_image("icon.png", format="base64")
print(f"Encoded size: {len(encoded)} characters")
decode_image
Decode a base64 string back to PIL Image.
- Parameters:
encoded_data
(str): Base64 encoded image data
- Returns:
PIL.Image.Image
: Decoded image
Example:
from PIL import Image
encoded = encode_image("icon.png")
image = decode_image(encoded)
print(f"Decoded image size: {image.size}")
compress_image
Compress an image with specified settings.
- Parameters:
image
(PIL.Image.Image): Image to compressquality
(int): JPEG quality (1-100)max_size
(Tuple[int, int], optional): Maximum dimensions
- Returns:
PIL.Image.Image
: Compressed image
Example:
from gui_image_studio import get_image
image = get_image("large_photo.jpg")
compressed = compress_image(image, quality=70, max_size=(800, 600))
validate_image
Validate that a file is a supported image format.
- Parameters:
image_path
(str): Path to the image file
- Returns:
bool
: True if image is valid and supported
Example:
if validate_image("unknown_file.xyz"):
print("Valid image file")
else:
print("Invalid or unsupported image")
Generated Code Structure
The generator creates Python modules with the following structure:
Basic Generated Module:
"""
Embedded images for GUI Image Studio
Generated on: 2024-06-22 10:30:00
Source folder: assets/icons
Total images: 5
"""
import base64
from io import BytesIO
from PIL import Image
from typing import Dict, List, Optional
# Image metadata
METADATA = {
'generated_on': '2024-06-22 10:30:00',
'source_folder': 'assets/icons',
'total_images': 5,
'compression': True,
'quality': 85
}
# Image data dictionary
IMAGES: Dict[str, str] = {
'icon_home': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQ...',
'icon_save': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQ...',
'icon_open': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQ...',
'logo_main': '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAA...',
'background': 'iVBORw0KGgoAAAANSUhEUgAAAQAAAAEA...',
}
def get_image(name: str) -> Image.Image:
"""
Get embedded image by name.
Args:
name: Name of the image to retrieve
Returns:
PIL Image object
Raises:
KeyError: If image name is not found
ValueError: If image data is corrupted
"""
if name not in IMAGES:
available = ', '.join(list_images())
raise KeyError(f"Image '{name}' not found. Available: {available}")
try:
data = base64.b64decode(IMAGES[name])
return Image.open(BytesIO(data))
except Exception as e:
raise ValueError(f"Failed to decode image '{name}': {e}")
def list_images() -> List[str]:
"""
List all available embedded images.
Returns:
List of image names
"""
return list(IMAGES.keys())
def get_image_info(name: str) -> Dict[str, any]:
"""
Get information about an embedded image.
Args:
name: Name of the image
Returns:
Dictionary with image information
"""
if name not in IMAGES:
raise KeyError(f"Image '{name}' not found")
image = get_image(name)
return {
'name': name,
'size': image.size,
'mode': image.mode,
'format': image.format,
'encoded_size': len(IMAGES[name])
}
def save_image(name: str, output_path: str) -> bool:
"""
Save an embedded image to file.
Args:
name: Name of the embedded image
output_path: Path where to save the image
Returns:
True if successful
"""
try:
image = get_image(name)
image.save(output_path)
return True
except Exception:
return False
Configuration Options
Compression Settings:
generator = ImageGenerator("assets")
# Enable compression with quality setting
generator.set_compression(True, quality=85)
# Set maximum image size
generator.set_compression(True, max_size=(512, 512))
# Disable compression for lossless embedding
generator.set_compression(False)
Format Filtering:
# Only include specific formats
generator = ImageGenerator(
"assets",
formats=['png', 'jpg'] # Exclude GIF, BMP, etc.
)
Custom Naming:
# Custom name mapping
generator.add_image("icons/home-24px.png", "icon_home")
generator.add_image("icons/save-24px.png", "icon_save")
Output Customization:
generator = ImageGenerator(
input_folder="assets",
output_file="my_resources.py",
module_name="my_resources",
template_file="custom_template.py" # Use custom template
)
Advanced Usage
Batch Processing Multiple Folders:
from gui_image_studio.generator import ImageGenerator
def generate_all_resources():
"""Generate resources from multiple folders."""
# Icons
icon_gen = ImageGenerator("assets/icons", "icons.py", "icons")
icon_gen.set_compression(True, quality=95, max_size=(64, 64))
icon_gen.generate()
# Images
image_gen = ImageGenerator("assets/images", "images.py", "images")
image_gen.set_compression(True, quality=80, max_size=(512, 512))
image_gen.generate()
# Backgrounds
bg_gen = ImageGenerator("assets/backgrounds", "backgrounds.py", "backgrounds")
bg_gen.set_compression(True, quality=70, max_size=(1024, 768))
bg_gen.generate()
Custom Template:
# Create custom template file
template = '''"""Custom embedded images module
Generated: 2024-01-01 12:00:00
"""
IMAGES = {}
def get_image(name):
"""Custom implementation"""
return IMAGES.get(name)
'''
generator = ImageGenerator("assets", template=template)
Progress Tracking:
class ProgressGenerator(ImageGenerator):
def generate(self):
images = self.list_images()
total = len(images)
for i, name in enumerate(images, 1):
print(f"Processing {i}/{total}: {name}")
# Process image...
return super().generate()
Integration with Build Systems:
# setup.py integration
from gui_image_studio.generator import ImageGenerator
def build_resources():
"""Build embedded resources during package build."""
generator = ImageGenerator("src/assets", "src/resources.py")
if not generator.generate():
raise RuntimeError("Failed to generate resources")
# Call during build
build_resources()
Error Handling
Common Exceptions:
FileNotFoundError
: Input folder or image files not foundPermissionError
: Cannot write to output fileValueError
: Invalid image format or corrupted dataMemoryError
: Image too large to process
Error Handling Example:
try:
generator = ImageGenerator("assets", "resources.py")
generator.generate()
except FileNotFoundError as e:
print(f"Input folder not found: {e}")
except PermissionError as e:
print(f"Cannot write output file: {e}")
except ValueError as e:
print(f"Invalid image data: {e}")
except Exception as e:
print(f"Unexpected error: {e}")
Validation:
# Validate before generation
generator = ImageGenerator("assets")
# Check input folder exists
if not os.path.exists(generator.input_folder):
raise FileNotFoundError(f"Input folder not found: {generator.input_folder}")
# Check for valid images
valid_images = [img for img in generator.list_images()
if validate_image(os.path.join(generator.input_folder, img))]
if not valid_images:
raise ValueError("No valid images found in input folder")
Performance Considerations
Memory Usage:
Large images consume significant memory during encoding
Consider using compression and size limits
Process images in batches for large folders
File Size:
Base64 encoding increases size by ~33%
Compression can significantly reduce embedded size
Balance quality vs. file size based on use case
Generation Time:
Compression adds processing time
Large images take longer to encode
Consider parallel processing for large batches
Optimization Tips:
# Optimize for size
generator.set_compression(True, quality=60, max_size=(256, 256))
# Optimize for quality
generator.set_compression(True, quality=95, max_size=(1024, 1024))
# No compression for small images
import os
image_files = [os.path.join(generator.input_folder, f) for f in generator.list_images()]
total_size = sum(os.path.getsize(f) for f in image_files if os.path.exists(f))
if total_size < 1024 * 1024: # 1MB
generator.set_compression(False)
Best Practices:
Use compression for distribution packages
Test different quality settings for your use case
Monitor memory usage with large image sets
Consider using multiple smaller generators for very large projects
Validate generated modules before deployment
Troubleshooting:
Common issues and solutions:
Out of memory: Reduce image sizes or process in batches
Slow generation: Enable compression and reduce quality
Large output files: Use higher compression and smaller max_size
Import errors: Check that all dependencies are installed
For more information, see the Examples and User Guide.