Principle:AUTOMATIC1111 Stable diffusion webui Postprocessing script execution
| Knowledge Sources | |
|---|---|
| Domains | Software Architecture, Plugin Systems, Image Processing, Pipeline Design |
| Last Updated | 2026-02-08 00:00 GMT |
Overview
Postprocessing script execution is the architectural principle of applying a sequence of independently-developed processing scripts to an image through an ordered pipeline, where each script can modify the image, attach metadata, or spawn additional output images.
Description
In extensible image processing applications, the set of operations that can be applied to an image is not fixed at design time. New operations (upscaling, face restoration, color correction, watermarking, captioning) may be added by users through a plugin mechanism. The postprocessing script execution pattern provides a framework for organizing these operations into a coherent pipeline.
The pattern has three key components:
- Script registration: Each postprocessing operation is encapsulated in a script class that declares its name, UI controls, and processing logic. Scripts are discovered and registered at startup.
- Pipeline ordering: Scripts are ordered by a combination of user-defined preference order (configurable in settings), a default order value declared by each script, and the script name as a tiebreaker. Users can also disable specific scripts from the pipeline.
- Two-pass execution: The pipeline runs in two phases:
- First pass (
process_firstpass): All scripts are called in order to examine the image and set shared state (e.g., target dimensions) without modifying the image. This allows later scripts to know what earlier scripts intend to do. - Second pass (
process): All scripts are called in order to actually modify the image. Each script can mutate the image in-place, add metadata to an info dictionary, or create extra output images.
- First pass (
Usage
Use the postprocessing script execution pattern when:
- Building an image processing system that needs to support user-installable processing plugins
- Operations need to communicate shared state before execution begins (two-pass pattern)
- A single input image may produce multiple output images (e.g., one upscaled with each of two different models)
- The order of operations matters and should be user-configurable (e.g., upscale before or after face restoration)
- Scripts need to be independently developed without knowledge of each other's internals
Theoretical Basis
Pipeline Architecture
The postprocessing script execution pattern is a hybrid of the Chain of Responsibility pattern and the Pipeline (Pipes and Filters) pattern:
class PostprocessedImage:
"""Wrapper that carries the image through the pipeline"""
image: PIL.Image # The current image state
info: dict # Metadata accumulated by scripts
shared: SharedInfo # State shared across all scripts
extra_images: list # Additional output images spawned by scripts
disable_processing: bool # Flag to skip further processing on this image
class ScriptPostprocessing:
"""Base class for all postprocessing plugins"""
name: str
order: int
def process_firstpass(self, pp: PostprocessedImage, **args):
"""Examine and set shared state (no modification)"""
pass
def process(self, pp: PostprocessedImage, **args):
"""Apply the actual processing"""
pass
Image Branching Pattern
A distinctive feature of this architecture is the image branching mechanism. When a script adds entries to extra_images, these become new images that subsequent scripts in the pipeline will also process. This creates a tree of image transformations:
Input Image
|
+-- Script A processes image
| |
| +-- extra_image_1 (e.g., upscaled with model A)
| +-- extra_image_2 (e.g., upscaled with model B)
|
+-- Script B processes image AND extra_image_1 AND extra_image_2
|
+-- Script C processes all accumulated images
|
Output: [image, extra_image_1, extra_image_2]
After each script processes an image, any newly spawned extra images are moved from the individual image's extra_images list to the global all_images list. This ensures that subsequent scripts see and process these new images. An image can set disable_processing = True to opt out of further script processing while still appearing in the final output.
Argument Dispatch
Each script declares UI controls that map to named parameters. The runner maintains a flat argument array where each script owns a contiguous slice defined by [args_from:args_to]. When invoking a script, the runner extracts the relevant slice and maps positional arguments back to named parameters using the control name registry.
User-Configurable Ordering
The execution order is determined by a scoring function that considers:
- The user's explicitly configured operation order (a list of script names in the desired sequence)
- The script's default
orderattribute (lower values run first) - The script name as a final tiebreaker
This allows users to, for example, configure face restoration to run before or after upscaling without modifying any script code.