Image Workflows
The high-engagement image post workflow generates static social media graphics with dynamic visuals and coherent text overlays designed to maximize engagement. Unlike video thumbnails, these are standalone graphic-design-oriented posts for platforms like Instagram, Twitter, LinkedIn, and Pinterest.
Quick Start
Section titled “Quick Start”# From a niche/topic — generates hooks, then imagesfabric run media/high-engagement-posts \ --input niche="AI productivity tools" \ --input platforms='["instagram-square", "twitter"]'
# From pre-existing hooks (skip hook generation)fabric run media/high-engagement-posts-from-hooks \ --input hook_ideas='[{"hook_text": "Stop using ChatGPT wrong"}]'
# Trending topics → posts (composed pipeline)fabric run global/hot-topics-to-postscurl -X POST "$FABRIC_URL/v1/workflows/run?name=media/high-engagement-posts" \ -H "Authorization: Bearer $FABRIC_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": { "niche": "AI productivity tools", "platforms": ["instagram-square", "twitter"] } }'Pipeline Architecture
Section titled “Pipeline Architecture”Standalone Pipeline
Section titled “Standalone Pipeline”gather_competitor_insights → gather_trend_signals → generate_hook_ideas →craft_image_prompts → generate_post_images → score_post_images →prepare_post_outputFrom Pre-Existing Hooks
Section titled “From Pre-Existing Hooks”craft_image_prompts → generate_post_images → score_post_images →prepare_post_outputTrending Topics Composed Pipeline
Section titled “Trending Topics Composed Pipeline”hot_topics_pipeline → bridge_topics_to_hooks → generate_hook_ideas →craft_image_prompts → generate_post_images → score_post_images →prepare_post_outputPipeline Stages
Section titled “Pipeline Stages”1. Craft Image Prompts
Section titled “1. Craft Image Prompts”Takes hook ideas and produces image_specs[] — one per hook and platform combination.
- Condenses hooks to 1-5 word overlays (ALL CAPS, bold)
- LLM generates per-hook: visual concept, color direction, layout type, typography guidance
- Applies high-engagement design principles:
- Typography is the hero — text IS the content
- High contrast (dark text on light, white/yellow on dark gradient)
- Color psychology: red/orange = urgency, yellow = attention, blue = trust
- Clean negative space, no busy backgrounds
- Readable at phone-screen thumbnail size
- Graphic design aesthetic, not photography
2. Generate Post Images
Section titled “2. Generate Post Images”Two generation paths, automatically selected based on the configured model:
Uses Gemini’s native text rendering to generate images with text baked in:
- Text overlay is part of the image generation prompt
- Produces coherent, styled, visually integrated text
- Best quality for text-heavy engagement posts
Two-stage approach since local diffusion models can’t reliably render text:
- Generate the background visual via local model (no text in prompt)
- Composite text overlay via PIL (ImageDraw + ImageFont)
- Semi-transparent gradient/band in the text zone
- ALL CAPS, white text with black stroke
- Auto-sized bold sans-serif font
Each image spec generates num_variants (default 3) variants for selection.
3. Score Post Images
Section titled “3. Score Post Images”Sends generated images back to Gemini vision for quality scoring (1-10) across:
| Dimension | Description |
|---|---|
text_readability | Can the text be read at thumbnail size? |
visual_impact | Does the image grab attention in a scroll? |
text_image_coherence | Do text and visual work together? |
click_appeal | Would you stop and click? |
platform_fit | Does it match the platform’s aesthetic? |
Images below threshold (default 6.0) are flagged. Set auto_regenerate=true to automatically retry low-scoring images.
4. Prepare Post Output
Section titled “4. Prepare Post Output”Ranks results by score and identifies the best variant per platform.
Input Parameters
Section titled “Input Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
niche | string | required | Content niche for hook generation |
hook_ideas | list[dict] | generated | Pre-existing hooks (skips generation) |
platforms | list[str] | ["instagram-square", "twitter"] | Target platforms |
brand_style | string | "" | Brand style guidelines |
num_variants | int | 3 | Variants per image spec |
auto_regenerate | bool | false | Auto-retry low-scoring images |
quality | string | "" | Quality preset (affects image model) |
Platform Sizes
Section titled “Platform Sizes”| Platform | Dimensions | Aspect Ratio |
|---|---|---|
instagram-square | 1080 x 1080 | 1:1 |
instagram-portrait | 1080 x 1350 | 4:5 |
instagram-story | 1080 x 1920 | 9:16 |
twitter | 1200 x 675 | 16:9 |
facebook | 1200 x 630 | 16:9 |
linkedin | 1200 x 627 | 16:9 |
pinterest | 1000 x 1500 | 2:3 |
threads | 1080 x 1080 | 1:1 |
Output
Section titled “Output”{ "posts": [ { "hook_text": "Stop using ChatGPT wrong", "overlay_text": "STOP USING CHATGPT WRONG", "platform": "instagram-square", "image_path": "/tmp/post_001.png", "scores": { "text_readability": 8, "visual_impact": 9, "text_image_coherence": 7, "click_appeal": 8, "platform_fit": 9 }, "overall_score": 8.2, "variant_index": 0, "generation_method": "gemini_native" } ], "best_per_platform": { "instagram-square": 0, "twitter": 2 }, "workflow": "high-engagement-posts"}Model Configuration
Section titled “Model Configuration”The workflow uses a post operation in the model configuration system:
| Profile | Model | Text Rendering |
|---|---|---|
| (default) | gemini-3.1-flash-image-preview | Native (in-image) |
premium | gemini-3.1-flash-image-preview | Native (in-image) |
local | sdxl-turbo | PIL overlay |
local-power | flux-schnell | PIL overlay |
Override per-run:
fabric run media/high-engagement-posts \ --input niche="AI tools" \ --input post_model="flux-schnell"Layout Types
Section titled “Layout Types”The craft_image_prompts task selects a layout type for text placement:
| Layout | Description |
|---|---|
centered | Semi-transparent dark rectangle centered, text centered within |
banner | Solid/gradient band across top or bottom third |
split | Dark half on left or right, text on the dark side |
gradient | Gradient overlay from bottom, text in lower portion |
AI Actor Portraits
Section titled “AI Actor Portraits”Workflow: image/generate-actors
Generates AI actor portrait images via Gemini Imagen 3, uploads them as Fabric assets, and populates a portrait gallery. Used to create consistent character images for video workflows.
# Default (1 professional actor, system gallery)fab-workflow image/generate-actors
# Custom actors for an orgfab-workflow image/generate-actors \ --input 'actors=[{"description": "young tech founder, casual style", "tags": ["male", "casual"]}]' \ --input gallery_name="my-actors" \ --input concurrency=4curl -X POST "$FABRIC_URL/v1/workflows/run?name=image/generate-actors" \ -H "Authorization: Bearer $FABRIC_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": { "actors": [ {"description": "young tech founder, casual style", "tags": ["male", "casual"]} ], "gallery_name": "my-actors", "concurrency": 4 } }'Pipeline
Section titled “Pipeline”resolve_actors → ensure_gallery → generate_and_upload → populate_gallery| Parameter | Type | Default | Description |
|---|---|---|---|
actors | list[dict] | 1 default actor | Actor descriptions with description and tags fields |
gallery_name | string | "default-portraits" | Gallery name to populate |
aspect_ratio | string | "3:4" | Portrait aspect ratio |
concurrency | int | 4 | Parallel generation limit |
Output
Section titled “Output”{ "generated_actors": [ { "description": "young tech founder, casual style", "image_path": "/tmp/actor_001.png", "asset_id": "018f...", "gallery_item_id": "..." } ], "gallery_id": "...", "gallery_name": "my-actors"}Image Editing (img2img)
Section titled “Image Editing (img2img)”Workflow: global/image-edit
Modifies an existing image using natural-language prompts via img2img. Analyzes the source image with vision, applies the edit through one of three backends (Gemini, fal.ai FLUX, or local diffusers), and evaluates the result.
# Basic editfab run global/image-edit \ --input image_path=photo.jpg \ --input prompt="Add dramatic lighting and warm tones"
# Control strength (0.0=preserve, 1.0=reimagine)fab run global/image-edit \ --input image_path=photo.jpg \ --input prompt="Make it look like a watercolor painting" \ --input strength=0.8
# Generate multiple variantsfab run global/image-edit \ --input image_path=photo.jpg \ --input prompt="Change the background to a beach sunset" \ --input num_variants=3 \ --input preserve='["subject", "composition"]'curl -X POST "$FABRIC_URL/v1/workflows/run?name=global/image-edit" \ -H "Authorization: Bearer $FABRIC_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": { "image_path": "photo.jpg", "prompt": "Add dramatic lighting and warm tones", "strength": 0.6 } }'from fabric_platform import FabricClient
fabric = FabricClient()run = fabric.run_workflow("global/image-edit", input={ "image_path": "product_photo.jpg", "prompt": "Make the background pure white, studio lighting", "strength": 0.5, "preserve": ["subject"], "num_variants": 2,})result = fabric.wait_for_run(run["id"])print(result["output"]["edited_image_path"])print(result["output"]["variant_paths"])Pipeline
Section titled “Pipeline”analyze_source (vision) → apply_edit (img2img) → evaluate_edit (score)Strength Parameter
Section titled “Strength Parameter”The strength parameter controls how much the output deviates from the original:
| Strength | Effect | Use Case |
|---|---|---|
0.1-0.3 | Subtle adjustments | Color correction, minor touch-ups |
0.4-0.6 | Moderate changes (default) | Style transfer, lighting changes, background swap |
0.7-0.9 | Major transformation | Artistic reimagining, genre change |
1.0 | Nearly full regeneration | Complete reimagining guided only by prompt |
Backends
Section titled “Backends”The workflow automatically routes to the best available backend:
| Backend | Model | Best For |
|---|---|---|
| Gemini (default) | gemini-2.5-flash | General-purpose editing with strong instruction following |
| fal.ai FLUX | fal-ai/flux/dev/image-to-image | High-quality style transfer and artistic edits |
| Local diffusers | sdxl-turbo, flux-schnell | Offline/free editing, fast iteration |
Override with --input image_edit_model="fal-ai/flux/dev/image-to-image" or set quality profiles (--input quality=local).
Preservation Constraints
Section titled “Preservation Constraints”| Constraint | What it preserves |
|---|---|
composition | Layout, framing, spatial arrangement |
colors | Color palette and color relationships |
subject | Main subject identity and features |
style | Artistic style, medium, technique |
lighting | Light direction, intensity, mood |
| Parameter | Type | Default | Description |
|---|---|---|---|
image_path | string | required | Source image (local path or URL) |
prompt | string | required | What to change |
strength | float | 0.6 | Deviation from original (0.0-1.0) |
preserve | list[str] | [] | Aspects to keep unchanged |
aspect_ratio | string | "" | Output aspect ratio (empty = preserve original) |
num_variants | int | 1 | Number of variants to generate (1-4) |
Output
Section titled “Output”{ "edited_image_path": "/tmp/fabric_edit_abc123.png", "variant_paths": ["/tmp/fabric_edit_def456.png"], "original_description": "A person standing in a park with autumn trees", "edit_description": "Added dramatic golden-hour lighting with warm orange tones", "fidelity_score": 8.5}SDK Function
Section titled “SDK Function”The edit_image() function is also available directly in the SDK for use in custom workflows:
from fabric_workflow_sdk import edit_image
# In any workflow taskedited_path = await edit_image( input, "Add a sunset sky", "source.jpg", strength=0.6,)