Skip to main content
This guide will get you editing photos with Imagen AI as quickly as possible using the quick_edit function.

Prerequisites

Before you begin, make sure you have:

The Simplest Example

The fastest way to edit photos is with the quick_edit function:
import asyncio
import os
from imagen_sdk import quick_edit, EditOptions

async def main():
    # Get API key from environment
    api_key = os.getenv("IMAGEN_API_KEY", "your_api_key_here")
    
    # Define editing options
    edit_options = EditOptions(
        crop=True,
        straighten=True
    )
    
    # Edit photos
    result = await quick_edit(
        api_key=api_key,
        profile_key=5700,
        image_paths=["photo1.nef", "photo2.dng", "photo3.cr2"],
        edit_options=edit_options,
        download=True
    )
    
    print(f"✅ Done! {len(result.downloaded_files)} edited photos")

asyncio.run(main())
Replace 5700 with your actual profile key from your Imagen AI account.

Understanding the Workflow

The quick_edit function handles the entire workflow for you:
1

Create Project

Automatically creates a new project in your Imagen AI account
2

Upload Images

Uploads your photos asynchronously to Imagen’s servers
3

Apply AI Editing

Processes photos using your AI profile and editing options
4

Download Results

Downloads the edited XMP files (and optionally exported JPEGs)

Complete Example

Here’s a more complete example from the SDK’s source code:
import asyncio
import os
from pathlib import Path
from imagen_sdk import quick_edit

async def main():
    """Edit photos with one function call"""
    
    # Get API key
    api_key = os.getenv("IMAGEN_API_KEY", "your_api_key_here")
    
    # Find photos to edit
    photos = [f for f in Path(".").glob("./sample_photos/*.dng") if f.is_file()]
    
    if not photos:
        print("No .dng files found. Add some photos to this directory.")
        return
    
    print(f"Editing {len(photos)} photos...")
    
    try:
        # Edit photos with AI
        result = await quick_edit(
            api_key=api_key,
            profile_key=5700,
            image_paths=[str(p) for p in photos],
            download=True,
            download_dir="edited",
            export=True,
        )
        
        print(f"✅ Done! {len(result.downloaded_files)} edited photos saved to ./edited/")
    
    except Exception as e:
        print(f"❌ Error: {e}")
        print("💡 Make sure your API key is set: export IMAGEN_API_KEY='your_key'")

if __name__ == "__main__":
    asyncio.run(main())

Editing Options

Customize how your photos are edited using EditOptions:
from imagen_sdk import EditOptions

# Basic editing
basic_options = EditOptions(
    crop=True,
    straighten=True
)

# Portrait photography
portrait_options = EditOptions(
    portrait_crop=True,
    smooth_skin=True,
    subject_mask=True
)

# Landscape/real estate
landscape_options = EditOptions(
    crop=True,
    perspective_correction=True,
    sky_replacement=True,
    window_pull=True,
    crop_aspect_ratio="16:9"
)
Some options are mutually exclusive:
  • Choose only one crop type: crop, portrait_crop, or headshot_crop
  • Choose only one straightening method: straighten or perspective_correction

Photography Types

Optimize AI processing by specifying your photography type:
from imagen_sdk import quick_edit, EditOptions, PhotographyType

edit_options = EditOptions(
    portrait_crop=True,
    smooth_skin=True,
    subject_mask=True
)

result = await quick_edit(
    api_key=api_key,
    profile_key=5700,
    image_paths=["ceremony_01.cr2", "portraits_01.nef"],
    photography_type=PhotographyType.WEDDING,
    edit_options=edit_options,
    download=True
)

Available Types

  • PhotographyType.WEDDING - Wedding ceremony & reception
  • PhotographyType.PORTRAITS - Individual/family portraits
  • PhotographyType.REAL_ESTATE - Property photography
  • PhotographyType.LANDSCAPE_NATURE - Outdoor/nature photography
  • PhotographyType.EVENTS - Corporate events, parties
  • PhotographyType.FAMILY_NEWBORN - Family and newborn sessions
  • PhotographyType.BOUDOIR - Boudoir photography
  • PhotographyType.SPORTS - Sports photography

Exporting to JPEG

You can also export final JPEG files directly:
result = await quick_edit(
    api_key="your_api_key",
    profile_key=5700,
    image_paths=["photo1.cr2", "photo2.nef"],
    export=True,  # Export to JPEG
    download=True,
    download_dir="wedding_edited"
)

print(f"XMP files: {len(result.downloaded_files)}")
print(f"Exported JPEGs: {len(result.exported_files)}")

Working Example: Wedding Photography

Here’s a complete wedding photography workflow:
import asyncio
from imagen_sdk import quick_edit, PhotographyType, EditOptions

async def process_wedding():
    # Define editing options for wedding portraits
    portrait_options = EditOptions(
        crop=True,
        straighten=True,
        smooth_skin=True,
        subject_mask=True
    )
    
    result = await quick_edit(
        api_key="your_api_key",
        profile_key=5700,
        image_paths=["ceremony_01.cr2", "portraits_01.nef", "reception_01.dng"],
        project_name="Sarah & Mike Wedding",
        photography_type=PhotographyType.WEDDING,
        edit_options=portrait_options,
        export=True,
        download=True,
        download_dir="wedding_edited"
    )
    
    print(f"Wedding photos ready: {len(result.downloaded_files)} XMP files")
    print(f"Exported JPEGs: {len(result.exported_files)} files")

asyncio.run(process_wedding())

Understanding the Results

The quick_edit function returns a QuickEditResult object with:
result = await quick_edit(...)

# Project information
print(f"Project UUID: {result.project_uuid}")

# Upload summary
print(f"Uploaded: {result.upload_summary.successful}/{result.upload_summary.total}")

# Download links (URLs)
print(f"XMP download links: {result.download_links}")
print(f"Export download links: {result.export_links}")

# Local file paths (if download=True)
print(f"Downloaded XMP files: {result.downloaded_files}")
print(f"Downloaded exported files: {result.exported_files}")

Error Handling

Handle errors gracefully with try/except:
import asyncio
from imagen_sdk import (
    quick_edit,
    EditOptions,
    AuthenticationError,
    UploadError,
    ProjectError,
    DownloadError
)

async def main():
    try:
        edit_options = EditOptions(crop=True, straighten=True)
        result = await quick_edit(
            api_key="your_api_key",
            profile_key=5700,
            image_paths=["photo1.cr2"],
            edit_options=edit_options,
            download=True
        )
        print(f"✅ Success! {len(result.downloaded_files)} photos edited")
    
    except AuthenticationError:
        print("❌ Invalid API key - check your credentials")
    except UploadError as e:
        print(f"❌ Upload failed: {e}")
    except ProjectError as e:
        print(f"❌ Project operation failed: {e}")
    except DownloadError as e:
        print(f"❌ Download failed: {e}")
    except Exception as e:
        print(f"❌ Error: {e}")

asyncio.run(main())

Common Issues

File Type Mixing

A single project cannot mix RAW and JPEG files. Create separate projects for different file types.
# ❌ WRONG - mixing file types
result = await quick_edit(
    api_key=api_key,
    profile_key=5700,
    image_paths=["photo1.cr2", "photo2.jpg"]  # Mixed types - will fail!
)

# ✅ CORRECT - separate projects
raw_result = await quick_edit(
    api_key=api_key,
    profile_key=5700,
    image_paths=["photo1.cr2", "photo2.nef"]  # All RAW
)

jpeg_result = await quick_edit(
    api_key=api_key,
    profile_key=5700,
    image_paths=["photo1.jpg", "photo2.jpeg"]  # All JPEG
)

Profile Key

Your profile key must match your file type. RAW profiles work with RAW files, and JPEG profiles work with JPEG files.

Next Steps

Now that you can edit photos with quick_edit, explore more advanced features:

ImagenClient

Use the full client for step-by-step control and progress tracking

Edit Options

Explore all available editing options in detail

Guides

Browse more real-world usage examples

Error Handling

Learn about exception types and troubleshooting

Build docs developers (and LLMs) love