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.
Problem
You have a batch of images that need AI-powered transformations—like
turning photos into paintings, adding stylistic effects, or modifying
content based on text prompts.
Solution
What’s in this recipe:
- Transform images using text prompts with Hugging Face Stable
Diffusion models
- Control transformation strength and quality settings
- Process batches of images automatically
You can iterate on transformations before adding them to your table. Use
.select() with .collect() to preview results on sample
images—nothing is stored in your table. If you want to collect only the
first few rows, use .head(n) instead of .collect(). Once you’re
satisfied, use .add_computed_column() to apply the transformation to
all images in your table.
For more on this workflow, see Get fast feedback on
transformations.
Setup
%pip install -qU pixeltable torch transformers diffusers accelerate
import pixeltable as pxt
from pixeltable.functions.huggingface import image_to_image
Load images
# Create a fresh directory (drop existing if present)
pxt.drop_dir('img2img_demo', force=True)
pxt.create_dir('img2img_demo')
Connected to Pixeltable database at: postgresql+psycopg://postgres:@/pixeltable?host=/Users/pjlb/.pixeltable/pgdata
Created directory ‘img2img_demo’.
<pixeltable.catalog.dir.Dir at 0x12f0dc3e0>
t = pxt.create_table('img2img_demo.images', {
'image': pxt.Image,
'prompt': pxt.String
})
Created table ‘images’.
t.insert([
{
'image': 'https://raw.githubusercontent.com/pixeltable/pixeltable/main/docs/resources/images/000000000285.jpg',
'prompt': 'oil painting style, vibrant colors, brushstrokes visible'
},
{
'image': 'https://raw.githubusercontent.com/pixeltable/pixeltable/main/docs/resources/images/000000000776.jpg',
'prompt': 'watercolor painting, soft edges, artistic'
},
])
Inserted 2 rows with 0 errors in 0.17 s (11.50 rows/s)
2 rows inserted.
# View original images and prompts
t.collect()
Use .select() to define the transformation, then .head(n) to preview
results on a subset of images. Nothing is stored in your table.
The image_to_image function requires: - image: The source image to
transform - prompt: Text describing the desired output - model_id: A
Hugging Face model ID that supports image-to-image (e.g.,
stable-diffusion-v1-5/stable-diffusion-v1-5)
# Preview transformation on first image
t.select(
t.image,
t.prompt,
image_to_image(
t.image,
t.prompt,
model_id='stable-diffusion-v1-5/stable-diffusion-v1-5'
)
).head(1)
You control how much the model modifies the original image using
strength (0.0-1.0): - Lower values (0.3-0.5): Subtle changes,
preserves more of the original - Higher values (0.7-1.0): Dramatic
changes, more creative freedom
You pass additional parameters through model_kwargs.
# Preview with lower strength (more preservation of original)
t.select(
t.image,
t.prompt,
image_to_image(
t.image,
t.prompt,
model_id='stable-diffusion-v1-5/stable-diffusion-v1-5',
model_kwargs={'strength': 0.5, 'num_inference_steps': 30}
)
).head(1)
Once you’re satisfied with the results, use .add_computed_column()
with the same expression. This processes all rows and stores the results
permanently in your table.
# Save as computed column
t.add_computed_column(
transformed=image_to_image(
t.image,
t.prompt,
model_id='stable-diffusion-v1-5/stable-diffusion-v1-5',
model_kwargs={'strength': 0.6, 'num_inference_steps': 25}
)
)
Added 2 column values with 0 errors in 63.11 s (0.03 rows/s)
2 rows updated.
# View original and transformed images side by side
t.select(t.image, t.prompt, t.transformed).collect()
Use reproducible results with seeds
You set a seed parameter to get the same output every time you run the
transformation.
# Add reproducible transformation
t.add_computed_column(
transformed_seeded=image_to_image(
t.image,
t.prompt,
model_id='stable-diffusion-v1-5/stable-diffusion-v1-5',
seed=42,
model_kwargs={'strength': 0.6}
)
)
Added 2 column values with 0 errors in 114.36 s (0.02 rows/s)
2 rows updated.
# View results
t.select(t.image, t.transformed_seeded).collect()
Explanation
How image-to-image works:
Image-to-image diffusion models take an existing image and a text
prompt, then generate a new image that blends the structure of the
original with the guidance from the prompt. The strength parameter
controls the balance—lower values preserve more of the original, while
higher values allow more dramatic transformations.
Model compatibility:
The image_to_image UDF uses AutoPipelineForImage2Image from the
diffusers library, which automatically detects the model type and
selects the appropriate pipeline. You use any compatible model:
stable-diffusion-v1-5/stable-diffusion-v1-5 - General-purpose,
runs on most hardware
stabilityai/stable-diffusion-xl-base-1.0 - Higher quality, needs
more VRAM
Key parameters:
strength (0.0-1.0): How much to transform the image
num_inference_steps: Quality vs speed tradeoff (more steps =
better quality)
guidance_scale: How closely to follow the prompt (7-8 is typical)
seed: For reproducible results
See also