Skip to main content
Flux image editing is based on the advanced Flux Kontext Max model, intelligently editing existing images according to text descriptions. Supports precise mask control, local file and online image input, and flexible aspect ratio output settings.
🎯 Precise Editing Using masks allows precise control of editing areas - white regions will be edited, black regions remain unchanged. Without mask, AI automatically determines editing regions.

🌟 Core Features

  • 🎭 Smart Editing: Intelligently modify image content based on text descriptions
  • 🖼️ Mask Support: Precisely control editing areas, protect important content
  • 📁 Flexible Input: Supports local files and online image URLs
  • 📐 Multiple Ratio Output: Supports 7 aspect ratios for different needs
  • 💰 Cost-Effective: Saves 12.5% compared to official pricing, no quality compromise

📋 Technical Specifications

FeatureFlux Kontext MaxDescription
APIYI Price$0.07/call12.5% savings vs official
Official Price$0.08/imageOriginal pricing
Input FormatsPNG, JPEG, WebP, GIFSupports common image formats
File SizeMax 20MB or 20MPSingle image limit
Aspect Ratio Range3:7 to 7:3From ultra-narrow portrait to ultra-wide landscape
API MethodOpenAI CompatibleStandard Images Edit API
Result URL10-minute validityDownload promptly
💡 Cost Savings: Calling Flux image editing through APIYI, combined with exchange rate advantage and top-up bonuses, saves over 12.5% compared to official pricing!

🚀 Quick Start

Basic Example - Local Image Editing

from openai import OpenAI

# Initialize client
client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.apiyi.com/v1"
)

def edit_local_image(image_path, prompt, aspect_ratio="1:1", mask_path=None,
                    seed=None, safety_tolerance=1, output_format="png"):
    """Edit local image"""
    try:
        # Prepare base parameters
        edit_params = {
            "model": "flux-kontext-max",
            "image": open(image_path, "rb"),
            "prompt": prompt,
            "extra_body": {
                "aspect_ratio": aspect_ratio,
                "safety_tolerance": safety_tolerance,
                "output_format": output_format
            }
        }

        # Optional parameters
        if seed is not None:
            edit_params["extra_body"]["seed"] = seed

        # If mask exists, add to parameters
        if mask_path:
            edit_params["mask"] = open(mask_path, "rb")

        # Call edit API
        response = client.images.edit(**edit_params)

        # Return edited image URL (note: URL valid for 10 minutes)
        return response.data[0].url

    except Exception as e:
        print(f"Edit failed: {e}")
        return None

    finally:
        # Ensure file handles are closed
        if 'edit_params' in locals():
            if 'image' in edit_params:
                edit_params['image'].close()
            if 'mask' in edit_params:
                edit_params['mask'].close()

# Usage example
edited_url = edit_local_image(
    image_path="portrait.jpg",
    prompt="Change the background to a beautiful sunset sky",
    aspect_ratio="2:3",
    seed=42,  # Reproducible results
    safety_tolerance=1,  # Safety level (0-2)
    output_format="jpeg"  # Or "png"
)

if edited_url:
    print(f"Edit complete: {edited_url}")
    print("Note: URL will expire after 10 minutes, download promptly!")

📝 Parameter Details

Core Parameters

ParameterTypeRequiredDescriptionDefault
modelstringYesModel name: flux-kontext-max-
imagefileYesOriginal image file (max 20MB or 20MP)-
promptstringYesEdit instructions describing desired modifications-
maskfileNoMask image specifying edit regions-

Parameters Passed via extra_body

ParameterTypeRangeDescriptionDefault
aspect_ratiostring-Output aspect ratio, e.g. “1:1”, “16:9""1:1”
seedinteger0-2147483647Random seed for result reproductionRandom
safety_toleranceinteger0-2Content safety level, 0=strict, 2=lenient1
output_formatstring”png”, “jpeg”Output image format”png”
🔄 Result Reproducibility: Using the same seed value and identical other parameters yields consistent editing results. This is helpful for debugging and client satisfaction testing.

Advanced Example - Online Image Editing

import requests
import tempfile
import os
from urllib.parse import urlparse

def download_image_from_url(url):
    """Download image from URL to temporary file"""
    try:
        response = requests.get(url, timeout=30)
        response.raise_for_status()

        # Get file extension
        parsed_url = urlparse(url)
        extension = parsed_url.path.split('.')[-1] if '.' in parsed_url.path else 'jpg'

        # Create temporary file
        temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=f'.{extension}')
        temp_file.write(response.content)
        temp_file.close()

        return temp_file.name

    except Exception as e:
        print(f"Image download failed: {e}")
        return None

def edit_online_image(image_url, prompt, aspect_ratio="1:1", mask_url=None):
    """Edit online image"""
    image_path = None
    mask_path = None

    try:
        # Download original image
        image_path = download_image_from_url(image_url)
        if not image_path:
            return None

        # Download mask (if exists)
        if mask_url:
            mask_path = download_image_from_url(mask_url)

        # Edit image
        result = edit_local_image(image_path, prompt, aspect_ratio, mask_path)

        return result

    finally:
        # Clean up temporary files
        for path in [image_path, mask_path]:
            if path and os.path.exists(path):
                os.unlink(path)

# Usage example
edited_url = edit_online_image(
    image_url="https://example.com/photo.jpg",
    prompt="Remove the person in the background, keep the foreground intact",
    aspect_ratio="16:9"
)

Batch Editing Example

def batch_edit_images(edit_tasks):
    """Batch edit images"""
    results = []

    for task in edit_tasks:
        try:
            print(f"Editing: {task['image_path']}")
            print(f"Edit instruction: {task['prompt']}")

            edited_url = edit_local_image(
                image_path=task['image_path'],
                prompt=task['prompt'],
                aspect_ratio=task.get('aspect_ratio', '1:1'),
                mask_path=task.get('mask_path')
            )

            if edited_url:
                # Download edited image
                filename = save_edited_image(edited_url, task['image_path'])

                results.append({
                    'original': task['image_path'],
                    'prompt': task['prompt'],
                    'edited_url': edited_url,
                    'saved_file': filename,
                    'success': True
                })
            else:
                results.append({
                    'original': task['image_path'],
                    'prompt': task['prompt'],
                    'success': False,
                    'error': 'API call failed'
                })

        except Exception as e:
            results.append({
                'original': task['image_path'],
                'prompt': task['prompt'],
                'success': False,
                'error': str(e)
            })

    return results

def save_edited_image(url, original_path):
    """Save edited image"""
    import time

    response = requests.get(url)
    if response.status_code == 200:
        # Generate new filename
        base_name = os.path.splitext(os.path.basename(original_path))[0]
        timestamp = int(time.time())
        filename = f"{base_name}_edited_{timestamp}.png"

        with open(filename, 'wb') as f:
            f.write(response.content)

        print(f"Saved: {filename}")
        return filename

    return None

# Batch editing example
edit_tasks = [
    {
        'image_path': 'photo1.jpg',
        'prompt': 'Change the sky to a dramatic stormy sky',
        'aspect_ratio': '3:2'
    },
    {
        'image_path': 'photo2.jpg',
        'prompt': 'Remove all people from the image',
        'aspect_ratio': '16:9',
        'mask_path': 'mask2.png'
    },
    {
        'image_path': 'photo3.jpg',
        'prompt': 'Make the image look like a vintage photograph',
        'aspect_ratio': '1:1'
    }
]

results = batch_edit_images(edit_tasks)

# Output results
for result in results:
    if result['success']:
        print(f"✅ {result['original']} -> {result['saved_file']}")
    else:
        print(f"❌ {result['original']} -> {result['error']}")

🎯 Professional Editing Techniques

1. Text Editing and Addition

Flux Kontext excels at handling text in images:
# Add text to image
add_text = edit_local_image(
    image_path="poster.jpg",
    prompt='Add the text "SALE 50% OFF" in bold red letters at the top center',
    aspect_ratio="3:2"
)

# Modify existing text
modify_text = edit_local_image(
    image_path="sign.jpg",
    prompt='Change the text from "Open" to "Closed"',
    aspect_ratio="1:1"
)

# Use quotes for text accuracy
precise_text = edit_local_image(
    image_path="banner.jpg",
    prompt='Replace the existing text with exactly "Welcome to Our Store"',
    aspect_ratio="7:3"
)

2. Intelligent Context Preservation

Flux understands image context for natural edits:
# Maintain lighting consistency
lighting_edit = edit_local_image(
    image_path="interior.jpg",
    prompt="Add a lamp in the corner, matching the existing warm lighting",
    aspect_ratio="16:9"
)

# Maintain perspective and proportions
perspective_edit = edit_local_image(
    image_path="street.jpg",
    prompt="Add a bicycle parked next to the building, matching the street perspective",
    aspect_ratio="3:2"
)

3. Character Consistency Maintenance

# Maintain character features
character_edit = edit_local_image(
    image_path="person.jpg",
    prompt="Change the person's shirt to blue while keeping all facial features identical",
    aspect_ratio="2:3",
    seed=42  # Use fixed seed for consistency
)

🎯 Editing Scenario Examples

1. Background Replacement

# Change background
background_edit = edit_local_image(
    image_path="portrait.jpg",
    prompt="Replace the background with a modern office environment",
    aspect_ratio="2:3"
)

# Remove background
remove_bg = edit_local_image(
    image_path="product.jpg",
    prompt="Remove the background, make it transparent",
    aspect_ratio="1:1"
)

2. Object Editing

# Add elements
add_element = edit_local_image(
    image_path="room.jpg",
    prompt="Add a beautiful plant in the corner of the room",
    aspect_ratio="16:9"
)

# Remove objects
remove_object = edit_local_image(
    image_path="street.jpg",
    prompt="Remove the car from the street, replace with empty road",
    aspect_ratio="3:2"
)

# Replace objects
replace_object = edit_local_image(
    image_path="table.jpg",
    prompt="Replace the apple on the table with an orange",
    aspect_ratio="1:1"
)

3. Style Transformation

# Artistic style
artistic_style = edit_local_image(
    image_path="landscape.jpg",
    prompt="Transform into an impressionist painting style",
    aspect_ratio="3:2"
)

# Season change
season_change = edit_local_image(
    image_path="park.jpg",
    prompt="Change from summer to autumn, add colorful fall leaves",
    aspect_ratio="16:9"
)

4. Precise Mask Editing

# Use mask for precise area editing
masked_edit = edit_local_image(
    image_path="group_photo.jpg",
    prompt="Blur the faces of the people in the masked area",
    aspect_ratio="3:2",
    mask_path="face_mask.png"  # White areas will be edited
)

🎨 Mask Creation Guide

1. Mask Principles

  • White Areas: Will be edited by AI
  • Black Areas: Remain unchanged
  • Gray Areas: Partially edited based on gray level

2. Mask Creation Tools

from PIL import Image, ImageDraw

def create_circular_mask(image_path, center, radius):
    """Create circular mask"""
    # Open original to get dimensions
    with Image.open(image_path) as img:
        width, height = img.size

    # Create black background mask
    mask = Image.new('L', (width, height), 0)
    draw = ImageDraw.Draw(mask)

    # Draw white circle (edit region)
    left = center[0] - radius
    top = center[1] - radius
    right = center[0] + radius
    bottom = center[1] + radius

    draw.ellipse([left, top, right, bottom], fill=255)

    # Save mask
    mask_path = f"circular_mask_{int(time.time())}.png"
    mask.save(mask_path)
    return mask_path

def create_rectangular_mask(image_path, bbox):
    """Create rectangular mask"""
    with Image.open(image_path) as img:
        width, height = img.size

    mask = Image.new('L', (width, height), 0)
    draw = ImageDraw.Draw(mask)

    # Draw white rectangle (edit region)
    draw.rectangle(bbox, fill=255)

    mask_path = f"rect_mask_{int(time.time())}.png"
    mask.save(mask_path)
    return mask_path

# Usage example
mask_path = create_circular_mask("photo.jpg", center=(500, 300), radius=100)
edited = edit_local_image("photo.jpg", "Add sunglasses", mask_path=mask_path)

💡 Best Practices

1. Prompt Writing Tips

Based on official documentation professional recommendations:
# ❌ Vague description
prompt = "make it better"

# ✅ Specific and detailed instructions
prompt = """
Remove the person standing in the background on the left side,
fill the area with matching landscape elements,
maintain the original lighting and perspective
"""

# ✅ Text editing with quotes
text_prompt = 'Change the store sign text to "OPEN 24/7" in red letters'

# ✅ Consistency instructions
consistency_prompt = """
Add a red sports car parked in the driveway,
matching the existing lighting conditions and perspective,
ensure it fits naturally with the house architecture
"""

# ✅ Precise local editing
precise_prompt = """
Change only the woman's dress color from blue to emerald green,
keep all other elements including lighting, background, and pose unchanged
"""

2. Advanced Prompt Patterns

def create_professional_prompt(action, target, context_preservation):
    """Create professional-grade editing prompt"""
    return f"""
    {action} {target}.
    Maintain the original {context_preservation}.
    Ensure the edit looks natural and seamlessly integrated.
    """

# Example usage
prompt = create_professional_prompt(
    action="Replace",
    target="the cloudy sky with a clear sunset sky",
    context_preservation="lighting, shadows, and overall atmosphere"
)

3. Aspect Ratio Selection Strategy

def recommend_aspect_ratio(edit_type, original_ratio=None):
    """Recommend aspect ratio based on edit type"""
    recommendations = {
        "portrait_edit": "2:3",
        "landscape_edit": "3:2",
        "social_media": "1:1",
        "banner_creation": "7:3",
        "mobile_content": "9:16",
        "desktop_wallpaper": "16:9"
    }

    # If original ratio exists, prioritize maintaining it
    if original_ratio:
        return original_ratio

    return recommendations.get(edit_type, "1:1")

4. Error Handling and Retry

import time

def edit_with_retry(image_path, prompt, max_retries=3, **kwargs):
    """Image editing with retry mechanism"""
    for attempt in range(max_retries):
        try:
            result = edit_local_image(image_path, prompt, **kwargs)
            if result:
                return result
        except Exception as e:
            if attempt < max_retries - 1:
                wait_time = 2 ** attempt  # Exponential backoff
                print(f"Edit failed, retrying in {wait_time}s... (attempt {attempt + 1}/{max_retries})")
                time.sleep(wait_time)
            else:
                print(f"Edit ultimately failed: {e}")
                raise e

    return None

5. Result URL and Download Management

Since Flux returns image URLs with only 10-minute validity, proper download timing is crucial:
import time
import requests
from concurrent.futures import ThreadPoolExecutor

def download_with_urgency(url, filename, max_attempts=3):
    """Urgent download considering 10-minute expiry"""
    start_time = time.time()

    for attempt in range(max_attempts):
        try:
            response = requests.get(url, timeout=30)
            response.raise_for_status()

            with open(filename, 'wb') as f:
                f.write(response.content)

            elapsed = time.time() - start_time
            print(f"✅ Download successful: {filename} (took {elapsed:.1f}s)")
            return True

        except Exception as e:
            elapsed = time.time() - start_time
            if elapsed > 540:  # Over 9 minutes, 1 minute buffer
                print(f"⚠️ Warning: Approaching URL expiry time!")

            if attempt < max_attempts - 1:
                print(f"Download failed, retrying... (attempt {attempt + 1}/{max_attempts})")
                time.sleep(1)
            else:
                print(f"❌ Download ultimately failed: {e}")
                return False

    return False

def batch_edit_with_immediate_download(tasks):
    """Batch edit with immediate download"""
    def edit_and_download(task):
        # Edit
        edited_url = edit_local_image(**task['edit_params'])
        if not edited_url:
            return {'success': False, 'error': 'Edit failed'}

        # Download immediately
        filename = f"{task['name']}_edited_{int(time.time())}.png"
        success = download_with_urgency(edited_url, filename)

        return {
            'success': success,
            'filename': filename if success else None,
            'url': edited_url,
            'task_name': task['name']
        }

    # Parallel processing to save time
    with ThreadPoolExecutor(max_workers=3) as executor:
        results = list(executor.map(edit_and_download, tasks))

    return results

⚠️ Important Notes

  1. File Limits:
    • Formats: Supports PNG, JPEG, WebP, non-animated GIF
    • Size: Max 20MB or 20 megapixels
    • Aspect ratio: Only supports 3:7 to 7:3 range
  2. URL Expiry Mechanism:
    • Edit result URLs are only valid for 10 minutes
    • Must complete download before URL expires
    • Recommend downloading immediately after edit completion
  3. Mask Requirements:
    • Mask image dimensions must exactly match original
    • White areas (255) = Edit regions
    • Black areas (0) = Protected regions
    • Gray areas = Partial editing
  4. Parameter Passing:
    • Flux-specific parameters must be passed via extra_body
    • Cannot use Flux proprietary parameters directly in top-level parameters
  5. Safety and Compliance:
    • safety_tolerance controls content moderation strictness
    • All edited content must comply with platform usage policies
    • Recommend using default safety level (1) for production
  6. Performance Optimization:
    • Control concurrency in batch editing to avoid API limits
    • Use seed parameter to ensure reproducible results
    • Choose appropriate output_format to balance quality and file size

🔍 FAQ

Q: Why do edit result URLs expire?

A: Flux’s official security design - all result URLs automatically expire 10 minutes after generation. This protects user privacy and reduces server storage pressure.

Q: How to create precise masks?

A: Use tools like Photoshop, GIMP, or generate via code. Key point: white areas (255) will be edited, black areas (0) remain unchanged, gray areas partially edited.

Q: How to ensure edit result consistency?

A: Use the same seed value and identical other parameters. This is helpful for A/B testing and client feedback iteration.

Q: Any tips for text editing?

A: Based on official recommendations: use quotes around specific text in prompts, like 'Change the sign to "OPEN 24/7"' for more accurate text results.

Q: How to choose safety_tolerance parameter?

A:
  • 0 = Strictest, suitable for enterprise/commercial environments
  • 1 = Balanced mode, recommended for most scenarios
  • 2 = Most lenient, suitable for creative/artistic projects

Q: What size images are supported?

A: Max 20MB or 20 megapixels supported. Recommend preprocessing large images for optimal performance.

Q: How to handle complex multi-step edits?

A: Can be achieved through multiple API calls, using each edit’s result as next input. Remember to download intermediate results within 10 minutes each time.

Q: Common reasons for edit failures?

A:
  1. Image exceeds size limit (20MB/20MP)
  2. Aspect ratio outside supported range (3:7 to 7:3)
  3. Mask dimensions don’t match original
  4. Prompt contains policy-violating content

🎯 Multi-Image Edit Solution

Although Flux API natively only supports single image editing, we provide a dual image composition editing solution, particularly suitable for pattern transfer and style fusion scenarios.

Core Advantages

Pattern Transfer

Precisely transfer design patterns to target images with natural fusion effect

Style Fusion

Combine characteristic elements from two images to create unique visual effects

Batch Processing

Supports automated processing of multiple image pairs, improving work efficiency

Smart Merge

Auto-handles image dimensions and splicing for optimal processing results

Implementation Principle

  1. Image Preprocessing: Auto-downloads and unifies heights of two images
  2. Smart Merge: Splices reference and base images left-right into single image
  3. AI Editing: Uses Flux Kontext Max to intelligently process merged image
  4. Result Output: Generates final result fusing characteristics from both images

Quick Usage

# Download multi-image processing script
curl -O https://raw.githubusercontent.com/apiyi-api/ai-api-code-samples/main/flux-Image-API/flux-simple-batch.sh
chmod +x flux-simple-batch.sh

# View usage instructions
./flux-simple-batch.sh --help

# Edit configuration and run
# 1. Set API_KEY
# 2. Configure IMAGE_PAIRS array
# 3. Customize BATCH_PROMPT
./flux-simple-batch.sh

Application Cases

Transfer pattern designs to clothing models, auto-adjusts size and position for natural wearing effect
BATCH_PROMPT="Transfer the pattern/design from the left image to the clothes of the model in the right image, with the size being 2/3 of the width of the chest, located in the middle. Make it look natural and well-integrated."
Combine images with different artistic styles to create unique mixed effects
BATCH_PROMPT="Combine the artistic style from the left image with the subject matter from the right image, creating a harmonious artistic fusion."
Apply decorative elements to architectural images, preview renovation effects
BATCH_PROMPT="Apply the decorative elements from the left image to the building in the right image, maintaining architectural harmony."
Batch Processing Tip: Script supports processing multiple image pairs at once, suitable for batch design work. All results and intermediate files are automatically saved for future use.
Dependency Requirements: Script requires jq (JSON processing), Python3 + PIL (image processing), and optional ImageMagick. See built-in script help for detailed installation instructions.
🎨 Professional Advice: For complex editing tasks, recommend testing effects with lower-cost models first, then use Flux Kontext Max for final editing once satisfied.