Skip to main content
Open in Kaggle  Open in Colab  Download Notebook
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()

Iterate: test transformation on a single image

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)

Iterate: adjust transformation strength

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)

Add: apply transformation to all images

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