Examples

Practical examples and use cases for Qwen Image Edit

Examples

Explore practical examples and real-world use cases for Qwen Image Edit. Each example includes complete code snippets and explanations.

Text Editing Examples

Adding Watermarks

Add copyright watermarks to protect your images:

import { QwenImageEdit } from '@qwen-image-edit/sdk';

const client = new QwenImageEdit({ apiKey: 'your-api-key' });

// Add a simple text watermark
const result = await client.textEdit({
  image: './original-photo.jpg',
  instruction: 'Add watermark "© 2024 Your Company" in bottom right corner',
  style: {
    fontSize: 16,
    color: '#FFFFFF',
    opacity: 0.7,
    fontFamily: 'Arial Bold'
  },
  position: { x: -50, y: -30 } // Negative values for bottom-right positioning
});

console.log('Watermarked image:', result.editedImage);

Multilingual Text Replacement

Replace text in different languages:

// English to Chinese
const englishToChinese = await client.textEdit({
  image: './menu-english.jpg',
  instruction: 'Replace "Welcome" with "欢迎"',
  preserveStyle: true
});

// Spanish to English
const spanishToEnglish = await client.textEdit({
  image: './sign-spanish.jpg',
  instruction: 'Change "Salida" to "Exit"',
  style: {
    fontSize: 'auto', // Automatically adjust font size
    color: 'preserve' // Keep original color
  }
});

Dynamic Text Generation

Generate personalized images with dynamic text:

const generatePersonalizedCard = async (userName: string, achievement: string) => {
  return await client.textEdit({
    image: './certificate-template.jpg',
    instruction: `Replace placeholder text with "${userName}" for name and "${achievement}" for achievement`,
    style: {
      fontSize: 24,
      color: '#2C3E50',
      fontFamily: 'Times New Roman'
    }
  });
};

// Usage
const certificate = await generatePersonalizedCard('John Doe', 'Excellence in AI');

Semantic Editing Examples

Style Transfer

Transform images into different artistic styles:

// Convert photo to oil painting
const oilPainting = await client.semanticEdit({
  image: './portrait.jpg',
  prompt: 'Transform into a classical oil painting with rich textures and warm colors',
  strength: 0.8
});

// Create anime-style artwork
const animeStyle = await client.semanticEdit({
  image: './character-photo.jpg',
  prompt: 'Convert to anime art style with vibrant colors and clean lines',
  strength: 0.9,
  preserveAreas: [
    { x: 100, y: 50, width: 200, height: 300 } // Preserve face area
  ]
});

Object Manipulation

Add, remove, or modify objects in images:

// Add objects to scene
const addObject = await client.semanticEdit({
  image: './empty-room.jpg',
  prompt: 'Add a modern sofa in the center and a coffee table in front of it',
  strength: 0.7
});

// Remove unwanted objects
const removeObject = await client.semanticEdit({
  image: './crowded-scene.jpg',
  prompt: 'Remove the person in red shirt from the background',
  strength: 0.6
});

// Change object properties
const changeColor = await client.semanticEdit({
  image: './red-car.jpg',
  prompt: 'Change the car color from red to blue while keeping everything else the same',
  strength: 0.5
});

Background Replacement

Replace or modify image backgrounds:

// Professional headshot background
const professionalBg = await client.semanticEdit({
  image: './casual-photo.jpg',
  prompt: 'Replace background with professional office setting, keep person unchanged',
  strength: 0.8,
  preserveAreas: [
    { x: 150, y: 100, width: 300, height: 400 } // Preserve person
  ]
});

// Seasonal transformation
const seasonalChange = await client.semanticEdit({
  image: './summer-landscape.jpg',
  prompt: 'Transform to winter scene with snow and bare trees',
  strength: 0.9
});

Batch Processing Examples

E-commerce Product Images

Process multiple product images with consistent styling:

const processProductImages = async (productImages: string[]) => {
  const operations = [
    {
      type: 'semantic-edit',
      prompt: 'Place on clean white background, professional lighting',
      strength: 0.6
    },
    {
      type: 'text-edit',
      instruction: 'Add "NEW" label in top-right corner',
      style: {
        fontSize: 20,
        color: '#FF4444',
        fontFamily: 'Arial Bold'
      }
    }
  ];

  return await client.batchEdit({
    images: productImages,
    operations,
    parallel: true
  });
};

// Process all product images
const productUrls = [
  './product1.jpg',
  './product2.jpg',
  './product3.jpg'
];

const processedProducts = await processProductImages(productUrls);

Social Media Content

Create consistent branding across social media posts:

const createSocialMediaPosts = async (images: string[], brandColors: string[]) => {
  const socialOperations = [
    {
      type: 'text-edit',
      instruction: 'Add "@YourBrand" watermark in bottom-left corner',
      style: {
        fontSize: 14,
        color: brandColors[0],
        opacity: 0.8
      }
    },
    {
      type: 'semantic-edit',
      prompt: `Apply brand color scheme with ${brandColors.join(', ')} accent colors`,
      strength: 0.4
    }
  ];

  return await client.batchEdit({
    images,
    operations: socialOperations,
    parallel: true
  });
};

Advanced Use Cases

Real-time Image Editor

Build a real-time image editing interface:

class RealTimeEditor {
  private client: QwenImageEdit;
  private currentImage: string;
  private editHistory: string[] = [];

  constructor(apiKey: string) {
    this.client = new QwenImageEdit({ apiKey });
  }

  async loadImage(imageUrl: string) {
    this.currentImage = imageUrl;
    this.editHistory = [imageUrl];
  }

  async applyEdit(instruction: string, options?: any) {
    const result = await this.client.textEdit({
      image: this.currentImage,
      instruction,
      ...options
    });

    this.currentImage = result.editedImage;
    this.editHistory.push(result.editedImage);
    
    return result;
  }

  async undo() {
    if (this.editHistory.length > 1) {
      this.editHistory.pop();
      this.currentImage = this.editHistory[this.editHistory.length - 1];
    }
    return this.currentImage;
  }

  getCurrentImage() {
    return this.currentImage;
  }
}

// Usage
const editor = new RealTimeEditor('your-api-key');
await editor.loadImage('./base-image.jpg');

// Apply multiple edits
await editor.applyEdit('Add title "My Artwork"');
await editor.applyEdit('Change background to gradient blue');
await editor.applyEdit('Add signature in bottom right');

// Undo last edit if needed
await editor.undo();

Automated Content Generation

Generate content automatically based on templates:

const generateMarketingMaterials = async (campaign: {
  productName: string;
  price: string;
  features: string[];
  targetAudience: string;
}) => {
  const templates = [
    './template-banner.jpg',
    './template-square.jpg',
    './template-story.jpg'
  ];

  const results = await Promise.all(
    templates.map(async (template) => {
      // Add product information
      let result = await client.textEdit({
        image: template,
        instruction: `Replace product name with "${campaign.productName}" and price with "${campaign.price}"`,
        style: { fontSize: 'auto', color: '#2C3E50' }
      });

      // Add features
      result = await client.textEdit({
        image: result.editedImage,
        instruction: `Add feature list: ${campaign.features.join(', ')}`,
        style: { fontSize: 14, color: '#7F8C8D' }
      });

      // Customize for target audience
      result = await client.semanticEdit({
        image: result.editedImage,
        prompt: `Adjust visual style to appeal to ${campaign.targetAudience}`,
        strength: 0.3
      });

      return result;
    })
  );

  return results;
};

// Generate campaign materials
const campaign = {
  productName: 'Smart Watch Pro',
  price: '$299',
  features: ['Heart Rate Monitor', 'GPS Tracking', '7-Day Battery'],
  targetAudience: 'fitness enthusiasts'
};

const marketingMaterials = await generateMarketingMaterials(campaign);

Error Handling and Best Practices

Robust Error Handling

const safeImageEdit = async (image: string, instruction: string, retries = 3) => {
  for (let attempt = 1; attempt <= retries; attempt++) {
    try {
      const result = await client.textEdit({ image, instruction });
      return result;
    } catch (error) {
      console.log(`Attempt ${attempt} failed:`, error.message);
      
      if (attempt === retries) {
        throw new Error(`Failed after ${retries} attempts: ${error.message}`);
      }
      
      // Exponential backoff
      await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000));
    }
  }
};

Performance Optimization

// Cache frequently used results
const cache = new Map<string, any>();

const cachedEdit = async (image: string, instruction: string) => {
  const cacheKey = `${image}-${instruction}`;
  
  if (cache.has(cacheKey)) {
    return cache.get(cacheKey);
  }
  
  const result = await client.textEdit({ image, instruction });
  cache.set(cacheKey, result);
  
  return result;
};

// Optimize image size before processing
const optimizeAndEdit = async (image: string, instruction: string) => {
  // Resize large images for faster processing
  const optimizedImage = await resizeImage(image, { maxWidth: 1024, maxHeight: 1024 });
  
  return await client.textEdit({
    image: optimizedImage,
    instruction
  });
};

Integration Examples

Next.js API Route

// pages/api/edit-image.ts
import { NextApiRequest, NextApiResponse } from 'next';
import { QwenImageEdit } from '@qwen-image-edit/sdk';

const client = new QwenImageEdit({ apiKey: process.env.QWEN_API_KEY });

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  if (req.method !== 'POST') {
    return res.status(405).json({ error: 'Method not allowed' });
  }

  try {
    const { image, instruction, type = 'text-edit' } = req.body;

    let result;
    if (type === 'text-edit') {
      result = await client.textEdit({ image, instruction });
    } else if (type === 'semantic-edit') {
      result = await client.semanticEdit({ image, prompt: instruction });
    }

    res.status(200).json(result);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
}

React Component

// components/ImageEditor.tsx
import React, { useState } from 'react';

const ImageEditor: React.FC = () => {
  const [image, setImage] = useState<string>('');
  const [instruction, setInstruction] = useState<string>('');
  const [result, setResult] = useState<string>('');
  const [loading, setLoading] = useState<boolean>(false);

  const handleEdit = async () => {
    setLoading(true);
    try {
      const response = await fetch('/api/edit-image', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ image, instruction })
      });
      
      const data = await response.json();
      setResult(data.editedImage);
    } catch (error) {
      console.error('Edit failed:', error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="image-editor">
      <input
        type="text"
        placeholder="Image URL"
        value={image}
        onChange={(e) => setImage(e.target.value)}
      />
      <input
        type="text"
        placeholder="Edit instruction"
        value={instruction}
        onChange={(e) => setInstruction(e.target.value)}
      />
      <button onClick={handleEdit} disabled={loading}>
        {loading ? 'Processing...' : 'Edit Image'}
      </button>
      {result && <img src={result} alt="Edited result" />}
    </div>
  );
};

export default ImageEditor;

These examples demonstrate the versatility and power of Qwen Image Edit across different use cases and integration scenarios. Start with simple text edits and gradually explore more advanced features as you become familiar with the API.