{"slug": "code-or-diffusion-a-field-guide-to-programmatic-image-generation", "title": "Code or diffusion? A field guide to programmatic image generation", "summary": "A developer's field guide distinguishes between programmatic image generation via code and diffusion models. The guide advises using code for structured visuals like diagrams and charts, which are cheaper, editable, and testable, while reserving diffusion for photorealistic textures. A hybrid approach combines a stock photo with a code-generated overlay for precise text.", "body_md": "A diagram is not a picture. It is a data structure that happens to be visible.\n\nTreat it as pixels and you pay pixel prices. $0.02 to $0.20 per diffusion render. No source file. No source-level way to fix a typo: you need another generation or an image-editing step.\n\nMost teams pay this by reflex, for things that were never really pictures: diagrams, charts, dashboards, labeled boxes.\n\nThere is a second path. The LLM writes code. A renderer turns the code into the image without another model call or image-generation API fee. Generation is probabilistic, but the accepted source artifact is not. Once stored, it is repeatable, editable, and diffable.\n\nThis is the field guide I wish I'd had. Three questions, asked in order, tell you which path to take and what it will cost. The rest of the series is the evidence behind each one.\n\nThis one question routes most cases.\n\nStructure is anything you could describe with coordinates, shapes, labels, and data. Diagrams, flowcharts, architecture, charts, dashboards, icons, logos, most illustrations, 3D geometry. If a developer could draw it from a spec, an LLM can write it as code.\n\nTexture is photoreal skin, brushstrokes, film grain, real faces, real places. For most prompt-driven workflows, code is the wrong abstraction for natural texture. Blender can render photorealism, but you pay for it in scene complexity and iteration time. This is diffusion's home turf.\n\nThe test: could you write instructions precise enough that two people would draw nearly the same thing? If yes, it is structure. Generate code. If it needs the \"surprise me\" of a trained image model, it is texture. Use diffusion.\n\nThere is a middle path. Put a stock or owned photo underneath, then add a code-generated overlay for the text and data that must be exact. Generating the overlay runs about $0.003, and the overlay carries validated text instead of asking an image model to reproduce it. That figure covers the overlay only. If the base image itself comes from diffusion, add its $0.02 to $0.20 on top.\n\nBefore the next two decisions, one asymmetry that matters more than the per-image price.\n\nBroken code fails loud. Invalid XML does not parse. A malformed SVG renders blank. The pipeline throws, CI goes red, nobody downstream sees it.\n\nValid code can still be wrong, and that failure is quiet too. An SVG with the label \"Amazn\" renders fine. So the loud failure only covers syntax. The durable advantage sits one level up: code exposes machine-checkable properties. Assert the SVG contains \"eu-central-1\". Assert the draw.io XML has exactly twelve nodes. Diff this week's chart against last week's and see the change, line by line. Wrong content becomes a test you can write once and run forever.\n\nA bitmap exposes far fewer native checks. Validating one usually means reconstructing structure through OCR or computer vision, an extra model judging another model's output. In practice the misspelled label, the reversed arrow, and the phantom service render successfully and wait for a human eyeball. Many defects therefore become recurring manual or vision-based review tasks. You cannot grep a PNG.\n\nCode does not guarantee correctness. It makes more of correctness testable. For anything that ends up in a customer deliverable, a compliance document, or an automated pipeline, that is the property to buy.\n\nIf it is structure, pick the lowest renderer class that covers the job. Every tier runs the same pattern: the LLM writes code, a renderer produces the visual without another image-generation API fee. You only pay for capability you use.\n\n| You need | Renderer | LLM writes |\n|---|---|---|\n| Static 2D vector, icons, illustration | SVG | markup |\n| Charts, KPIs, parameterized visuals | SVG (templated) | markup + data |\n| Diagrams with domain icons (AWS, etc.) | draw.io XML | XML + verified stencils |\n| Particles, simulations, interactive 2D | Canvas / p5.js | JavaScript |\n| 3D in the browser | Three.js | JS scene |\n| Math / explainer video | Manim | Python scene |\n| Game scenes, levels | Godot (.tscn) | scene text |\n| Photorealistic 3D stills | Blender | bpy Python |\n| AAA-grade real-time frames | Unreal Engine | Python API |\n\nTwo clarifications keep this honest.\n\nFirst, the ladder is not a strict capability gradient. Godot is not \"more capable\" than Manim. Each tier unlocks a capability class the previous one cannot reach: templated data, domain stencils, animation, 3D, physics, photorealism. Pick by class, not by rank. Output tokens grow roughly an order of magnitude across the ladder, from a few hundred for a simple SVG to several thousand for a full 3D scene. Treat those as approximations. Complexity of the scene drives the count more than the renderer does.\n\nSecond, \"no API fee\" is not \"free.\" SVG, draw.io, Canvas, and many Three.js scenes render in a browser with low operational overhead. Manim, Godot, Blender, and Unreal need a runtime and consume real compute: `blender --background`\n\n, `godot --headless`\n\n. That headless step is what turns this into a pipeline. Prompt in, PNG out, no human in the loop. AWS Batch or Amazon ECS is the right home for heavy Blender or video renders. AWS Lambda covers lightweight jobs like SVG-to-PNG rasterization that fit inside its 15-minute limit.\n\nThe law: cost equals output tokens times model rate. What the tier buys is a quality ceiling. I ran the same crayon-illustration prompt across the Amazon Bedrock lineup.\n\n| Model | Out tokens | Cost | What you get |\n|---|---|---|---|\n| Amazon Nova Pro | 1,102 | $0.004 | valid but primitive, bare shapes |\n| Claude Haiku 4.5 | 3,419 | $0.014 | structured, gradients, glow, animation |\n| Claude Sonnet 5 | 6,128 | $0.062 | good composition, minor filter quirks |\n| Claude Opus 4.8 | 4,089 | $0.105 | cleanest, most deliberate |\n| Claude Fable 5 | 7,531 | $0.381 | most sophisticated, slowest |\n\nSame prompt, a roughly 95x cost range from Nova Pro to Fable. Two test prompts is a small sample, so read this as directional, not as law. Two observations survive even at this size.\n\nCapability drives quality, not token count. Opus produced the cleanest result with fewer output tokens than Sonnet, 4,089 against 6,128. More tokens from a weaker model do not buy composition.\n\nIn this illustration test, returns diminished above Opus. Fable's result was the most sophisticated, but not four times better at four times the price. Across these two prompts, the Nova-to-Haiku jump produced the clearest quality gain per dollar, and the Opus-to-Fable jump the least.\n\nThe second prompt, a network-topology diagram, held the pattern. Nova Pro drew plain circles and lines for $0.007. Haiku added depth, labels, and animated data-flow dashes for $0.011.\n\nCheap is not free of consequences. Cheap is primitive.\n\n*The rule:*\n\nNow scale it. At the measured $0.004 inference cost, 1,000 outputs of comparable token length would run about $4 in model spend, excluding retries, validation, and rendering infrastructure. And every output is a diffable text asset in Git. The same volume through diffusion runs $20 to $200 in per-image fees and yields 1,000 opaque bitmaps you can neither edit nor verify.\n\n**Methodology.** Output tokens and latency are measured; dollar figures are calculated from Amazon Bedrock on-demand rates, July 2026, us-east-1. Two rates need flags. The Sonnet 5 figure uses launch pricing of $2/$10 per million input/output tokens, valid through August 31, 2026; at the standard $3/$15 rate from September 1 the same run costs about $0.093. Fable 5 was measured after access was restored on July 1, 2026. Using it requires opting in to provider_data_share; AWS states that inputs and outputs may be retained for up to 30 days for abuse detection and potential human review. For regulated workloads, treat that as an architectural decision, not an invocation detail.\n\nOne technique cheats the cost-quality trade-off entirely. Hand a cheap model a well-designed SVG skeleton and let it fill in only the data. You get premium-looking output at Nova-tier cost, because the polish lives in the template you wrote once, not in tokens you buy every call. It follows the same economic principle as prompt caching: amortize the expensive, stable part across many cheaper operations.\n\nThis also shrinks the failure surface. The model no longer designs the image. It fills slots in a structure you already verified. Less freedom, fewer ways to be wrong.\n\nMeasured dollar figures live in the benchmark above. The matrix uses cost classes because model cost tracks scene complexity, not just the path. Anchors from the benchmark: very low is under $0.01, medium is a few cents, high approaches $0.10 per image.\n\n| Need | Path | Model tier | Model cost | Editable | Runtime |\n|---|---|---|---|---|---|\n| Architecture / flow diagram | draw.io XML | Haiku to Sonnet | Low to medium | Full XML | Browser |\n| Chart / KPI / dashboard | SVG (templated) | Nova to Haiku | Very low | Full | Browser |\n| Icon / logo mark | SVG | Nova | Very low | Full | Browser |\n| Editorial illustration | SVG + style doc | Sonnet to Opus | Medium to high | Full | Browser |\n| Generative / creative art | Canvas / p5.js | Sonnet | Medium | Full | Browser |\n| 3D product / scene | Three.js / Blender | Sonnet to Opus | Highly variable | Full | Browser / CLI |\n| Math explainer video | Manim | Sonnet | Variable | Full | Python + ffmpeg |\n| Game asset / level | Godot .tscn | Sonnet | Variable | Full | Godot |\n| Photoreal person / place | Diffusion | n/a | Per-image, $0.02-0.20 | No | API |\n| Photo + exact text overlay | Hybrid (photo + SVG) | Haiku | Very low + base image | Partial | Browser |\n\nUse diffusion when the value is in the texture. Photoreal people and places. Painterly surfaces, ink bleed, film grain. The happy accident of a trained model.\n\nUse it for exploration. Ten variations of a mood board in thirty seconds is something no renderer gives you.\n\nAnd use it when the image is a genuine one-off that nobody will ever edit, version, or audit. If machine-checkability is worth nothing to you, you are not losing anything by giving it up.\n\nThe point is not purity. It is spending diffusion money only where diffusion earns it, and letting code handle the structured majority for cents.\n\nEach article in the series is one branch of this framework, with runnable Amazon Bedrock code:\n\nLive demo with a cost calculator and gallery: [labs.p.awsnavigator.com/code-as-canvas](https://labs.p.awsnavigator.com/code-as-canvas/index.html). Source: [github.com/vidanov/llm-programmatic-image-gen](https://github.com/vidanov/llm-programmatic-image-gen).\n\n*Built with Claude on Amazon Bedrock. Alexey Vidanov · GitHub · dev.to*", "url": "https://wpnews.pro/news/code-or-diffusion-a-field-guide-to-programmatic-image-generation", "canonical_source": "https://dev.to/aws-builders/code-or-diffusion-a-field-guide-to-programmatic-image-generation-2jm7", "published_at": "2026-07-10 17:54:43+00:00", "updated_at": "2026-07-10 18:14:45.055211+00:00", "lang": "en", "topics": ["artificial-intelligence", "large-language-models", "developer-tools", "generative-ai"], "entities": ["AWS", "SVG", "draw.io", "Three.js", "Canvas", "p5.js", "Blender"], "alternates": {"html": "https://wpnews.pro/news/code-or-diffusion-a-field-guide-to-programmatic-image-generation", "markdown": "https://wpnews.pro/news/code-or-diffusion-a-field-guide-to-programmatic-image-generation.md", "text": "https://wpnews.pro/news/code-or-diffusion-a-field-guide-to-programmatic-image-generation.txt", "jsonld": "https://wpnews.pro/news/code-or-diffusion-a-field-guide-to-programmatic-image-generation.jsonld"}}