Image Generation
An image is generated from a prompt, in an art style, at the shape of your canvas. This page covers describing an image, generating it, changing it afterwards, and placing it.
Describing an image
from imaginaryarts import ImageAssetBuilder
hero = ImageAssetBuilder(
prompt="An old Greek philosopher on a rocky shore at dawn, holding a cup of seawater up to the light",
name="thales-shore",
)| Parameter | Meaning |
|---|---|
prompt | What the picture shows. Required. |
art_style | Overrides the builder-wide style for this one image. A preset, or a plain string used as a custom style description. |
files | Reference images to show the model alongside the prompt. See below. |
name | A label for the saved files. Optional, and free to change. |
take | Bump to 2, 3, ... to generate the same prompt again and get a different result. |
ImageAssetBuilder.from_scene(scene) builds one from an authored scene, taking its prompt and its name.
Generating
AssetsBuilder takes the builders and generates them together:
from imaginaryarts import AssetsBuilder, ImageModel, ImageDirection, ImageDirectionStyle
images = AssetsBuilder(
project=project,
model=ImageModel(name="nanobanana2", size=(1080, 1920)),
direction=ImageDirection(art_style=ImageDirectionStyle.DarkAcademia()),
assets=[hero, ImageAssetBuilder(prompt="...")],
).build()
images[0].path # the PNG on disk
images[0].prompt # the full prompt that was sent, style includedThe result indexes and iterates like a list, in the order you gave. .add(builder) appends one more before build().
ImageModel names the model and the shape. size sets the aspect ratio rather than exact pixels, so (1080, 1920) means "vertical, 9 by 16"; "1080x1920" is accepted too. Nano Banana 2 is the only image model today.
Writing prompts that work
The model is good, but it draws what it is told. A few habits produce reliable results:
- Lead with the subject and the setting, then lighting, then mood. "A lighthouse keeper on the gallery of the tower, storm at sea, lantern light on the rain" beats "dramatic lighthouse scene".
- One moment, one focal point. A prompt that lists five things gets a collage.
- Frame for the canvas. Vertical video favours a single figure or a tall composition; say "full-length" or "close-up" when it matters.
- Don't ask for text. Lettering in generated images is unreliable; add words with
add_static_textinstead. - Leave the style to the style. The art style is prepended automatically; repeating "watercolor" in every prompt only fights it.
Editing an image
Sometimes an image is nearly right. Rather than re-rolling and hoping, edit it: the model is given the existing picture and an instruction, and changes only what the instruction asks for.
hero = ImageAssetBuilder(prompt="...") \
.edit("give the philosopher a closed, thoughtful expression") \
.edit("make the sky stormier")Each .edit() returns a new builder with one more step; the original is untouched. Each step is cached on the one before it, so adding a third edit costs one generation, and removing the last one costs nothing because the earlier result is still on disk. take= on an edit re-rolls just that step:
.edit("make the sky stormier", take=2)An edit instruction can mention references with @name, just like a prompt.
Reference images
To have a real person, product or place in a generated image, or to keep a generated character consistent across images, give the model reference pictures. The full mechanism, named references you can mention with @, is described in Using reference characters, props, and environments.
For a one-off, files= attaches images directly to a single prompt:
ImageAssetBuilder(
prompt="Return a photo of Elon Musk (see reference image) laughing on a heap of dollar bills",
files=[ImageFile(ROOT / "assets/references/elon.jpg")],
)Placing an image
An image has no duration, so it is placed for an interval, usually one that comes from the voice:
placed = voiceover.tile()
for i, scene in enumerate(placed.scenes):
video.add_image(images[i], interval=[scene.start, scene.end]) \
.add_effect(Effects.FadeIn(250)).add_effect(Effects.FadeOut(250))
video.add_motion(CameraMotion.KenBurns(), interval=[scene.start, scene.end])A slow camera motion is what makes a still feel like footage; see Camera Motion.
What is cached
An image's identity is its full prompt (so the art style is part of it), the model, the size, the references it mentions, and its take. Change any of those and it regenerates; change anything else, including its position in the list or its name, and it does not. See Re-generating and iterating.