cd /news/generative-ai/your-image-to-video-pipeline-needs-a… Β· home β€Ί topics β€Ί generative-ai β€Ί article
[ARTICLE Β· art-137081] src=dev.to β†— pub= topic=generative-ai verified=true sentiment=Β· neutral

Your image-to-video pipeline needs an intermediate representation

A developer argues that image-to-video generation pipelines fail when a single still image is passed directly to a video model, because a frame encodes appearance but not camera path, shot boundaries, pacing, or transition triggers. The proposed fix is a richer intermediate representation: a storyboard with a shot list, per-transition camera motivations, and explicit pacing, which reportedly let one 15-second concept succeed on the first attempt after five prior failures. The writeup frames the problem as missing constraints being filled in with the model's average-case priors rather than randomness.

by read6 min views2 publishedSep 22, 2026

Adapted for DEV Community from an article originally published on the Oimi blog. The engineering framing, prompt schemas and failure analysis below are written for people building generation pipelines rather than for end users.

Originally published at oimi.ai/en/blog/gpt-image-2-seedance-2-workflow

Everyone building on image-to-video models hits the same wall. You have one great still. You feed it to the video model with a motion prompt. You get something that looks plausible for two seconds and then falls apart.

We watched a creator burn five generations on the same 15-second concept β€” a continuous shot through a medieval market ending on a lone knight in a tavern. Every attempt failed differently:

The sixth attempt succeeded on the first try. The only thing that changed was what got passed between the two calls: instead of a single image, a storyboard with a timeline and camera motivations.

That's the whole article. The interesting part is why it works, and it has nothing to do with prompt wording.

Here's the framing that made it click for me: you are not sending an image to a model. You are sending an interface β€” and a single frame is a lossy one.

A still image encodes: appearance, composition, lighting, style. That's it.

It does not encode: camera path, shot boundaries, pacing, what triggers each transition, or where the viewer's attention should be at second 9. You are implicitly asking the model to invent all of that, and its priors for "what should happen next" are generic. Hence shuffle.

The failure isn't randomness. It's missing constraints being filled in with the average case. Same class of bug as an API that accepts options: any and guesses.

So the fix isn't a better motion prompt. It's choosing a richer intermediate representation.

A storyboard panel is only half of it. The panel gives you appearance; the annotations give you the schedule. What actually needs to survive the handoff:

Must encode Why it can't be deferred
Subject invariants Identity has to be fixed before any frame is generated, or every shot reinterprets the face
Shot list with boundaries If the model picks its own shot count, you get whatever it feels like
Camera motivation per transition This is the one everyone skips, and it's the one that matters most (below)
Pacing per segment Without explicit durations, the model front-loads the action and starves the ending
Lens / camera height Otherwise shot 4 has a different focal character than shot 3 and reads as a different film

Notice that four of these five are temporal, not visual. A single image can only carry the first one. That asymmetry is the entire argument for the storyboard step.

The practical version of this: stop writing prompts as prose and write them as a structured spec that gets rendered to prose. Not literally JSON in the API β€” but thinking in fields keeps you from silently dropping a constraint.

For the image step, the spec looks roughly like:

task: "storyboard infographic, 16:9, 12 panels"
style:
  base: "rough graphite storyboard sketch, monochrome pencil shading"
  no: ["cartoon", "modern elements"]
character:
  identity: "locks once, reused verbatim across all panels"
scene:
  location: "medieval market street, stone city, dusk"
  props: ["wooden stalls", "banners", "livestock", "carts"]
shots:
  - { n: 1,  lens: 50mm, framing: "street-level close",    action: "woman buys apples, pays coins" }
  - { n: 2,  lens: 50mm, framing: "medium close-up",       action: "hands exchanging coin and fruit" }
  - { n: 3,  lens: 35mm, framing: "foreground interruption", trigger: "horse crosses frame" }
  - { n: 4,  lens: 35mm, framing: "medium tracking",        follows: "wooden cart" }
  - { n: 12, lens: 35mm, framing: "interior reveal",        action: "knight alone, candlelight, lifts gaze" }
annotations:
  - "motion arrows"
  - "lens focal lengths written on each panel"
  - "terms like tracking / push-in / redirect / focus handoff / foreground interruption"

Then the video step is a different, much smaller spec β€” because everything visual is already locked:

format: "continuous shot, motivated camera movement, 15s"
timeline:
  - { t: "0:00-0:03", shot: "street-level, woman selecting fruit, hands coins" }
  - { t: "0:03-0:05", shot: "cart crosses foreground, camera catches and tracks it" }
  - { t: "0:05-0:07", shot: "cart brushes banner, banner swings, reveals chickens scattering" }
  - { t: "0:07-0:09", shot: "boy chases chickens, camera follows boy" }
  - { t: "0:09-0:12", shot: "boy runs past tavern, door swings open" }
  - { t: "0:12-0:15", shot: "camera glides through doorway, knight at corner table lifts gaze" }

The division of labour that makes this work: the image model owns appearance, the video model owns motion. Every constraint you push into the image step is a constraint the video model doesn't have to guess. Every constraint you leave in the video step costs you a retry.

This is the highest-value idea in the whole pipeline, and it comes from film rather than ML. Spielberg's staging rule: every camera movement must have a motivation β€” something on screen justifies why the camera moves now.

Applied to generation, it turns the shot list into a chain where each transition is triggered by an on-screen event:

Transition Trigger in frame Camera response
1 β†’ 2 coins exchanged push in on hands
2 β†’ 3 horse enters frame hold, let it occlude (interruption)
3 β†’ 4 cart passes pick up and track the cart
4 β†’ 5 cart brushes banner banner sweeps across lens
5 β†’ 6 chickens scatter follow the movement outward
6 β†’ 7 boy runs past tavern door chase into the doorway

Read that as a system and it's not a prompt anymore β€” it's a state machine where every transition is event-driven. Nothing moves the camera without a cause in frame. The model doesn't need to invent continuity logic, because the continuity logic is already in the input.

Compare the two attempts on measurable outcomes:

Single image + prompt Storyboard + timeline
Attempts needed 5+ 1
Transitions Random jump cuts Every cut motivated by scene action
Shot coverage Elements lost All 12 shots reproduced
Camera Moves arbitrarily Every move has a motivation

The 5Γ— retry reduction is the number to care about if you're paying per generation. The storyboard call is not overhead; it's the cheapest call in the pipeline, and it's the one that eliminates the expensive retries.

Being honest about the limits, because a pipeline diagram that only shows the happy path is useless:

The framing I'd leave you with: treat the generation stack like any other multi-stage pipeline. Define the interface between stages, make the handoff lossy in only one direction, and you stop debugging outputs and start debugging inputs.

I work on Oimi AI, which is where this storyboard-to-video pipeline runs end to end β€” the image step, the storyboard annotations, and the video call on one canvas instead of exporting between apps. If you want the specs rather than my paraphrase, the fashion case we ran is published as a runnable template.

If you've got a better answer for the retry-economics problem β€” fewer calls, or a cheaper way to validate a shot before paying for the video model β€” I'd like to hear it in the comments.

── more in #generative-ai 4 stories Β· sorted by recency
── more on @oimi 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/your-image-to-video-…] indexed:0 read:6min 2026-09-22 Β· β€”