Module

core.resources.processor

Image processing backend with caching.

Provides the actual image processing using Pillow, with:

  • Versioned cache to avoid reprocessing
  • Atomic writes for parallel build safety
  • Memory optimization for large images
  • Multiple output formats (WebP, AVIF, JPEG, PNG)

Cache Structure:

.bengal/image-cache/ ├── v1_abc123_fill_def456.webp # Processed images ├── v1_abc123_fill_def456.json # Metadata (dimensions, etc.) └── ...

Cache Key Format:

v{schema}{source_hash}{operation}_{spec_hash}.{ext}

Thread Safety:

Uses atomic file writes (tempfile + rename) to prevent corruption during parallel builds where multiple workers might process the same image simultaneously.

Memory Management:

For images >10MP, uses PIL.Image.draft() to reduce memory usage by loading at reduced resolution.

Classes

CachedResult 6
Cached processing result metadata.

Cached processing result metadata.

Attributes

Name Type Description
output_path Path
rel_permalink str
width int
height int
format str
file_size int
ImageProcessor 14
Image processing with caching. Uses Pillow for processing, with optional libvips for performance. …

Image processing with caching.

Uses Pillow for processing, with optional libvips for performance. Caches processed images in .bengal/image-cache/.

Thread Safety: Uses atomic file writes to prevent corruption during parallel builds. Cache reads are lock-free; writes use tempfile + rename pattern.

Memory Management: For images >10MP, uses chunked processing via PIL.Image.draft() to reduce peak memory usage.

Attributes

Name Type Description
site

Site instance for configuration

cache_dir

Path to image cache directory

Methods

process 3 Any | None
Process image with caching. Checks cache first, processes only if cache miss. …
def process(self, source: Path, operation: str, spec: str) -> Any | None

Process image with caching.

Checks cache first, processes only if cache miss.

Cache key includes:

  • Schema version (for cache invalidation on format changes)
  • Source path + mtime
  • Operation + spec
Parameters
Name Type Description
source

Path to source image

operation

Processing operation (fill, fit, resize, filter)

spec

Operation parameters

Returns
Any | None ProcessedImage on success, None on error
Internal Methods 11
__init__ 1
Initialize processor with site configuration.
def __init__(self, site: Any)
Parameters
Name Type Description
site

Site instance (for root_path and output configuration)

_cache_key 3 str
Generate cache key with schema version. Format: v{schema}_{source_hash}_{op}_{…
def _cache_key(self, source: Path, operation: str, spec: str) -> str

Generate cache key with schema version.

Format: v{schema}{source_hash}{op}_{spec_hash}

Parameters
Name Type Description
source
operation
spec
Returns
str
_get_cached 2 CachedResult | None
Check if cached result exists.
def _get_cached(self, cache_key: str, params: Any) -> CachedResult | None
Parameters
Name Type Description
cache_key

Cache key string

params

ProcessParams for format determination

Returns
CachedResult | None CachedResult if cache hit, None if miss
_cache_result 2
Cache processing result atomically. Uses tempfile + rename pattern for atomic …
def _cache_result(self, cache_key: str, result: Any) -> None

Cache processing result atomically.

Uses tempfile + rename pattern for atomic writes.

Parameters
Name Type Description
cache_key
result
_do_process 3 Any | None
Actually process the image using Pillow.
def _do_process(self, source: Path, operation: str, params: Any) -> Any | None
Parameters
Name Type Description
source

Path to source image

operation

Processing operation

params

ProcessParams

Returns
Any | None ProcessedImage on success, None on error
_fill 2 Image.Image
Resize and crop to exact dimensions.
def _fill(self, img: Image.Image, params: Any) -> Image.Image
Parameters
Name Type Description
img

PIL Image

params

ProcessParams with width, height, anchor

Returns
Image.Image Processed PIL Image
_fit 2 Image.Image
Resize to fit within dimensions.
def _fit(self, img: Image.Image, params: Any) -> Image.Image
Parameters
Name Type Description
img

PIL Image

params

ProcessParams with width, height

Returns
Image.Image Processed PIL Image (not upscaled)
_resize 2 Image.Image
Resize with aspect ratio preservation.
def _resize(self, img: Image.Image, params: Any) -> Image.Image
Parameters
Name Type Description
img

PIL Image

params

ProcessParams with width and/or height

Returns
Image.Image Processed PIL Image
_apply_filters 2 Image.Image
Apply image filters. Currently supports: grayscale, blur
def _apply_filters(self, img: Image.Image, params: Any) -> Image.Image
Parameters
Name Type Description
img

PIL Image

params

ProcessParams (anchor field contains filter spec)

Returns
Image.Image Processed PIL Image
_smart_crop 2 Image.Image
Smart cropping with face/feature detection. Falls back to center crop if smart…
def _smart_crop(self, img: Image.Image, target: tuple[int, int]) -> Image.Image

Smart cropping with face/feature detection.

Falls back to center crop if smartcrop is not installed.

Parameters
Name Type Description
img

PIL Image

target

(width, height) tuple

Returns
Image.Image Cropped PIL Image
_anchor_to_centering 1 tuple[float, float]
Convert anchor name to PIL centering tuple.
def _anchor_to_centering(self, anchor: str) -> tuple[float, float]
Parameters
Name Type Description
anchor

Anchor name (center, top, bottom, etc.)

Returns
tuple[float, float] (x, y) centering tuple for ImageOps.fit

Functions

get_cache_stats 1 dict[str, Any]
Get image cache statistics.
def get_cache_stats(site: Any) -> dict[str, Any]
Parameters
Name Type Description
site Any

Site instance

Returns
dict[str, Any]
clear_cache 1 int
Clear the image cache.
def clear_cache(site: Any) -> int
Parameters
Name Type Description
site Any

Site instance

Returns
int