示例

Qwen Image Edit 的实用示例和用例

示例

探索 Qwen Image Edit 的实用示例和真实世界用例。每个示例都包含完整的代码片段和说明。

文本编辑示例

添加水印

为图片添加版权水印以保护您的图像:

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

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

// 添加简单的文本水印
const result = await client.textEdit({
  image: './original-photo.jpg',
  instruction: '在右下角添加水印 "© 2024 您的公司"',
  style: {
    fontSize: 16,
    color: '#FFFFFF',
    opacity: 0.7,
    fontFamily: 'Arial Bold'
  },
  position: { x: -50, y: -30 } // 负值表示右下角定位
});

console.log('添加水印的图片:', result.editedImage);

多语言文本替换

替换不同语言的文本:

// 英文转中文
const englishToChinese = await client.textEdit({
  image: './menu-english.jpg',
  instruction: '将 "Welcome" 替换为 "欢迎"',
  preserveStyle: true
});

// 西班牙文转英文
const spanishToEnglish = await client.textEdit({
  image: './sign-spanish.jpg',
  instruction: '将 "Salida" 改为 "Exit"',
  style: {
    fontSize: 'auto', // 自动调整字体大小
    color: 'preserve' // 保持原始颜色
  }
});

动态文本生成

生成带有动态文本的个性化图片:

const generatePersonalizedCard = async (userName: string, achievement: string) => {
  return await client.textEdit({
    image: './certificate-template.jpg',
    instruction: `将占位符文本替换为姓名 "${userName}" 和成就 "${achievement}"`,
    style: {
      fontSize: 24,
      color: '#2C3E50',
      fontFamily: 'Times New Roman'
    }
  });
};

// 使用方法
const certificate = await generatePersonalizedCard('张三', 'AI 领域卓越表现');

语义编辑示例

风格转换

将图片转换为不同的艺术风格:

// 将照片转换为油画
const oilPainting = await client.semanticEdit({
  image: './portrait.jpg',
  prompt: '转换为古典油画风格,具有丰富的纹理和温暖的色彩',
  strength: 0.8
});

// 创建动漫风格艺术作品
const animeStyle = await client.semanticEdit({
  image: './character-photo.jpg',
  prompt: '转换为动漫艺术风格,具有鲜艳的色彩和清晰的线条',
  strength: 0.9,
  preserveAreas: [
    { x: 100, y: 50, width: 200, height: 300 } // 保留面部区域
  ]
});

物体操作

在图片中添加、移除或修改物体:

// 向场景添加物体
const addObject = await client.semanticEdit({
  image: './empty-room.jpg',
  prompt: '在中央添加一个现代沙发,前面放一个咖啡桌',
  strength: 0.7
});

// 移除不需要的物体
const removeObject = await client.semanticEdit({
  image: './crowded-scene.jpg',
  prompt: '从背景中移除穿红衣服的人',
  strength: 0.6
});

// 改变物体属性
const changeColor = await client.semanticEdit({
  image: './red-car.jpg',
  prompt: '将汽车颜色从红色改为蓝色,保持其他所有内容不变',
  strength: 0.5
});

背景替换

替换或修改图片背景:

// 专业头像背景
const professionalBg = await client.semanticEdit({
  image: './casual-photo.jpg',
  prompt: '将背景替换为专业办公环境,保持人物不变',
  strength: 0.8,
  preserveAreas: [
    { x: 150, y: 100, width: 300, height: 400 } // 保留人物
  ]
});

// 季节转换
const seasonalChange = await client.semanticEdit({
  image: './summer-landscape.jpg',
  prompt: '转换为冬季场景,有雪和光秃的树木',
  strength: 0.9
});

批量处理示例

电商产品图片

使用一致的样式处理多个产品图片:

const processProductImages = async (productImages: string[]) => {
  const operations = [
    {
      type: 'semantic-edit',
      prompt: '放置在干净的白色背景上,专业照明',
      strength: 0.6
    },
    {
      type: 'text-edit',
      instruction: '在右上角添加 "NEW" 标签',
      style: {
        fontSize: 20,
        color: '#FF4444',
        fontFamily: 'Arial Bold'
      }
    }
  ];

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

// 处理所有产品图片
const productUrls = [
  './product1.jpg',
  './product2.jpg',
  './product3.jpg'
];

const processedProducts = await processProductImages(productUrls);

社交媒体内容

在社交媒体帖子中创建一致的品牌形象:

const createSocialMediaPosts = async (images: string[], brandColors: string[]) => {
  const socialOperations = [
    {
      type: 'text-edit',
      instruction: '在左下角添加 "@您的品牌" 水印',
      style: {
        fontSize: 14,
        color: brandColors[0],
        opacity: 0.8
      }
    },
    {
      type: 'semantic-edit',
      prompt: `应用品牌配色方案,使用 ${brandColors.join(', ')} 作为强调色`,
      strength: 0.4
    }
  ];

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

高级用例

实时图片编辑器

构建实时图片编辑界面:

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;
  }
}

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

// 应用多个编辑
await editor.applyEdit('添加标题 "我的艺术作品"');
await editor.applyEdit('将背景改为渐变蓝色');
await editor.applyEdit('在右下角添加签名');

// 如需要可以撤销最后一次编辑
await editor.undo();

自动化内容生成

基于模板自动生成内容:

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) => {
      // 添加产品信息
      let result = await client.textEdit({
        image: template,
        instruction: `将产品名称替换为 "${campaign.productName}",价格替换为 "${campaign.price}"`,
        style: { fontSize: 'auto', color: '#2C3E50' }
      });

      // 添加功能特性
      result = await client.textEdit({
        image: result.editedImage,
        instruction: `添加功能列表:${campaign.features.join(', ')}`,
        style: { fontSize: 14, color: '#7F8C8D' }
      });

      // 为目标受众定制
      result = await client.semanticEdit({
        image: result.editedImage,
        prompt: `调整视觉风格以吸引${campaign.targetAudience}`,
        strength: 0.3
      });

      return result;
    })
  );

  return results;
};

// 生成营销材料
const campaign = {
  productName: '智能手表 Pro',
  price: '¥1999',
  features: ['心率监测', 'GPS 追踪', '7天续航'],
  targetAudience: '健身爱好者'
};

const marketingMaterials = await generateMarketingMaterials(campaign);

错误处理和最佳实践

健壮的错误处理

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} 次尝试失败:`, error.message);
      
      if (attempt === retries) {
        throw new Error(`${retries} 次尝试后失败: ${error.message}`);
      }
      
      // 指数退避
      await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000));
    }
  }
};

性能优化

// 缓存常用结果
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;
};

// 处理前优化图片大小
const optimizeAndEdit = async (image: string, instruction: string) => {
  // 调整大图片尺寸以加快处理速度
  const optimizedImage = await resizeImage(image, { maxWidth: 1024, maxHeight: 1024 });
  
  return await client.textEdit({
    image: optimizedImage,
    instruction
  });
};

集成示例

Next.js API 路由

// 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: '方法不允许' });
  }

  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 组件

// 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('编辑失败:', error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="image-editor">
      <input
        type="text"
        placeholder="图片 URL"
        value={image}
        onChange={(e) => setImage(e.target.value)}
      />
      <input
        type="text"
        placeholder="编辑指令"
        value={instruction}
        onChange={(e) => setInstruction(e.target.value)}
      />
      <button onClick={handleEdit} disabled={loading}>
        {loading ? '处理中...' : '编辑图片'}
      </button>
      {result && <img src={result} alt="编辑结果" />}
    </div>
  );
};

export default ImageEditor;

这些示例展示了 Qwen Image Edit 在不同用例和集成场景中的多样性和强大功能。从简单的文本编辑开始,随着您对 API 的熟悉逐渐探索更高级的功能。