This documentation page is also available as an interactive notebook. You can launch the notebook in
Kaggle or Colab, or download it for use with an IDE or local Jupyter installation, by clicking one of the
above links.
Pixeltable’s Reve integration lets you call Reve’s image generation API
directly from tables so you can iterate on visuals without leaving your
data workflows.
What is Reve?
Reve is an image generation and editing service. In its v2 API, the
previously separate create, edit, and remix operations are unified
into a single create endpoint, so Pixeltable exposes just one UDF:
reve.create(). Depending on what you pass it, the same function covers
three use cases:
- Generate a brand-new image from a text prompt.
- Edit an existing image by passing it as a single reference.
- Remix several images together by passing multiple references.
You attach reference images with the references argument and point to
them from the prompt with <frame>0</frame>, <frame>1</frame>, etc.
(0-indexed, in the order you pass them).
reve.create() returns a dictionary with two keys: 'image' (the
generated image) and 'layout' (JSON metadata describing the generated
image, such as the prompt and the regions Reve laid out). In this
notebook we only need the image, so we index into the result with
['image'].
Documentation
Prerequisites
Important: Reve API calls consume credits based on your plan—monitor
your usage to avoid unexpected charges. Images sent to Reve are
processed on Reve’s servers outside your environment, so do not upload
sensitive, private, or confidential images.
We’ll start by installing Pixeltable, configuring your API key, creating
a directory, and setting up a table. Then we’ll walk through each use
case of reve.create()—generate, edit, and remix—one at a time.
To read more about working with API keys in Pixeltable, see
Configuration.
Setup
Create a Pixeltable directory to keep the tables for this demo separate
from anything else you’re working on.
Connected to Pixeltable database at: postgresql+psycopg://postgres:@/pixeltable?host=/Users/sergeymkhitaryan/.pixeltable/pgdata
Created directory ‘reve_demo’.
<pixeltable.catalog.dir.Dir at 0x132cde020>
We’ll create a Pixeltable table that starts with a prompt and a source
image, and ends with a final scene. The table we’ll build up to will
require two inputs per row:
- A prompt for creating a background scene image. We’ll pass this
prompt to
reve.create() to generate a scene.
- An existing source image. We’ll pass this image to
reve.create()
as a single reference to edit it, and then it will be ready as the
foreground image.
Finally, we’ll pass both the background scene and the edited foreground
image to reve.create() as multiple references to remix them into one
final scene.
Created table ‘solarpunk_scenes’.
To read more about creating tables, see Tables and Data
Operations.
You can look at the schema for this table:
Now, we’ll insert values for our first row. We need to provide a text
prompt to generate a scene and a source image to edit.
Inserted 1 row with 0 errors in 0.04 s (28.19 rows/s)
1 row inserted.
To read more about inserting data, see Bringing
Data.
And we can peek at our starter table with a single row:
Generate new imagery from a prompt
Use reve.create() with just a prompt when you want Reve to synthesize
an entirely new image. In Pixeltable, we place this function call inside
a computed column. Feel free to change the prompt. Here we ask for a
solarpunk oasis city.
Since reve.create() returns a dictionary, we index it with ['image']
so the new_image column holds the generated image itself (stored as a
proper image, with a file URL, thumbnails, and so on).
Reve’s raw outputs can be large, so we pass a postprocessing step that
downscales each generated image to at most 1024 pixels on its longest
side. We define it once and reuse it for every reve.create() call
below.
Added 1 column value with 0 errors in 46.36 s (0.02 rows/s)
1 row updated.
To read more about computed columns in Pixeltable, see Computed
Columns.
By default, Pixeltable saves all generated media outputs to a media
directory. We can see the file path by using the fileurl property.
Add Reve parameters
reve.create() accepts several optional parameters to customize the
output:
aspect_ratio: desired image aspect ratio, e.g. ‘3:2’, ‘16:9’, ‘1:1’,
etc.
version: specific model version to use (defaults to latest if not
specified).
postprocessing: a list of postprocessing operations to apply to the
generated image. We’re already using it to downscale images
(fit_1024 above); other operations include effects,
e.g. [{'process': 'effect', 'effect_name': 'low_light'}].
model_kwargs: additional keyword arguments to pass through to the
Reve API.
This adds a second image column using the same prompt that renders in a
square frame.
Added 1 column value with 0 errors in 58.36 s (0.02 rows/s)
1 row updated.
To read more about reve.create(), see reve.create
UDF.
Edit an existing photo with a single reference
When you pass a single image in references and refer to it from the
prompt with <frame>0</frame>, reve.create() behaves like an editor:
it transforms that image according to your natural-language
instructions. We already have a source_image column in our table from
the initial setup.
We can now add a computed column that calls reve.create() with
references=[spunk_t.source_image] to modify the source image, indexing
the result with ['image'] as before.
This editing prompt is integrated into our computed column logic in
Pixeltable, as opposed to our generate example where we saved the prompt
as its own column. This means that the same prompt will be applied to
any new rows that we insert into this table. We will phrase the editing
prompt to reflect this table’s solarpunk theme, but otherwise keep it
general. This way, we don’t need to provide a specific prompt for every
new table row.
Added 1 column value with 0 errors in 58.24 s (0.02 rows/s)
1 row updated.
We can use collect() to see the new image:
Remix multiple references
When you pass multiple images in references, reve.create() blends
them together. Inside the prompt string, you reference each image with a
numbered <frame> placeholder, matching the order of the references
list:
<frame>0</frame> refers to references[0]
<frame>1</frame> refers to references[1]
- etc.
You can optionally specify aspect_ratio, version, and other
parameters just like before.
In the next cell we place the edited subject from <frame>0</frame>
(the first entry in the references list) into the scene from
<frame>1</frame> (the second entry). Because new_image and
edited_subject are already extracted image columns, we can pass them
directly as references.
Added 1 column value with 0 errors in 76.41 s (0.01 rows/s)
1 row updated.
To read more about reve.create(), see reve.create
UDF.
Insert a new row
So far, we have been building up our table schema with a single row. Now
we’ll insert a new row, with two fresh input values:
- A text prompt to generate the scene image and
- A source image to edit and then remix into that scene.
Pixeltable will then automatically make the desired Reve API calls and
populate the computed columns.
Inserted 1 row with 0 errors in 153.10 s (0.01 rows/s)
1 row inserted.
Now we can inspect both outputs because the insert() in Pixeltable
triggers our computed columns to update for any that are missing values
(existing images we already generated are not changed because Pixeltable
does incremental updates). For example, here is our inserted image and
our edited image:
Here are our two remixed images created by Reve:
All together, we generated a new scene image, edited an existing image
of a person, then remixed both together to reimagine an existing person
in our new scene.
Review Reve in Pixeltable
Below is a quick recap of the three ways we used the single
reve.create() UDF inside Pixeltable tables. Each call reads input
parameters and, after indexing the result with ['image'], writes the
generated image into a computed column.
Generate (prompt only)
- Input parameter: A prompt inserted as a row inside a Pixeltable
Edit (one reference)
- Input parameter: A source image of type
pxt.Image, passed as
references=[...]
- Usage reminder: The edit instructions live inline inside the
add_computed_column() call, and refer to the image with
<frame>0</frame>
Remix (multiple references)
- Input parameters: We started with two image columns
- How the prompt references them:
references=[my_table.image00, my_table.image01]
- Inside the prompt,
<frame>0</frame> points at references[0] and
<frame>1</frame> points at references[1]
- Usage reminder: Always keep the placeholders and the order of the
references list in sync; add more <frame>n</frame> tags if you
pass more reference images.
Learn more
If you build something with Reve, let us know!