示例

各种使用场景的实用示例和代码片段

示例

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

文本编辑示例

添加水印

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

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

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

# 示例 (简体中文)

本文档提供了 QwenImageEdit SDK 的各种使用示例,涵盖了从基础图像操作到高级图像编辑功能。每个示例都包含 JavaScript 代码片段,帮助您快速上手。

## 1. 图像基础操作

### 1.1. 移除背景

从图像中智能地移除背景,保留主体。

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

const qwenImageEdit = new QwenImageEdit({ apiKey: 'YOUR_API_KEY' });

async function removeBackground(imageUrl) {
  try {
    const result = await qwenImageEdit.image.removeBackground({
      imageUrl: imageUrl,
    });
    console.log('背景移除成功:', result.outputUrl);
    return result.outputUrl;
  } catch (error) {
    console.error('背景移除失败:', error);
  }
}

// 示例用法
// removeBackground('https://example.com/your-image.jpg');

1.2. 调整大小

将图像调整到指定的宽度和高度,支持多种缩放模式。

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

const qwenImageEdit = new QwenImageEdit({ apiKey: 'YOUR_API_KEY' });

async function resizeImage(imageUrl, width, height) {
  try {
    const result = await qwenImageEdit.image.resize({
      imageUrl: imageUrl,
      width: width,
      height: height,
      fit: 'cover', // 'cover', 'contain', 'fill', 'inside', 'outside'
    });
    console.log('图像调整大小成功:', result.outputUrl);
    return result.outputUrl;
  } catch (error) {
    console.error('图像调整大小失败:', error);
  }
}

// 示例用法
// resizeImage('https://example.com/your-image.jpg', 800, 600);

1.3. 应用滤镜

对图像应用各种预设滤镜,如灰度、模糊、锐化等。

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

const qwenImageEdit = new QwenImageEdit({ apiKey: 'YOUR_API_KEY' });

async function applyFilter(imageUrl, filterType) {
  try {
    const result = await qwenImageEdit.image.applyFilter({
      imageUrl: imageUrl,
      filter: filterType, // 例如 'grayscale', 'sepia', 'blur', 'sharpen'
    });
    console.log('应用滤镜成功:', result.outputUrl);
    return result.outputUrl;
  } catch (error) {
    console.error('应用滤镜失败:', error);
  }
}

// 示例用法
// applyFilter('https://example.com/your-image.jpg', 'grayscale');

1.4. 添加文本

在图像上添加自定义文本,支持字体、颜色、大小和位置。

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

const qwenImageEdit = new QwenImageEdit({ apiKey: 'YOUR_API_KEY' });

async function addTextToImage(imageUrl, text, x, y) {
  try {
    const result = await qwenImageEdit.image.addText({
      imageUrl: imageUrl,
      text: text,
      x: x,
      y: y,
      font: 'Arial', // 可选
      fontSize: 30,   // 可选
      color: '#FFFFFF', // 可选
    });
    console.log('添加文本成功:', result.outputUrl);
    return result.outputUrl;
  } catch (error) {
    console.error('添加文本失败:', error);
  }
}

// 示例用法
// addTextToImage('https://example.com/your-image.jpg', 'Hello Qwen!', 50, 50);

1.5. 叠加图像

将一个图像叠加到另一个图像上,支持位置和透明度。

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

const qwenImageEdit = new QwenImageEdit({ apiKey: 'YOUR_API_KEY' });

async function overlayImage(baseImageUrl, overlayImageUrl, x, y) {
  try {
    const result = await qwenImageEdit.image.overlay({
      baseImageUrl: baseImageUrl,
      overlayImageUrl: overlayImageUrl,
      x: x,
      y: y,
      opacity: 0.7, // 可选,0.0 到 1.0
    });
    console.log('叠加图像成功:', result.outputUrl);
    return result.outputUrl;
  } catch (error) {
    console.error('叠加图像失败:', error);
  }
}

// 示例用法
// overlayImage('https://example.com/base.jpg', 'https://example.com/overlay.png', 100, 100);

1.6. 裁剪图像

从图像中裁剪出指定区域。

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

const qwenImageEdit = new QwenImageEdit({ apiKey: 'YOUR_API_KEY' });

async function cropImage(imageUrl, x, y, width, height) {
  try {
    const result = await qwenImageEdit.image.crop({
      imageUrl: imageUrl,
      x: x,
      y: y,
      width: width,
      height: height,
    });
    console.log('裁剪图像成功:', result.outputUrl);
    return result.outputUrl;
  } catch (error) {
    console.error('裁剪图像失败:', error);
  }
}

// 示例用法
// cropImage('https://example.com/your-image.jpg', 0, 0, 200, 200);

1.7. 旋转图像

将图像旋转指定角度。

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

const qwenImageEdit = new QwenImageEdit({ apiKey: 'YOUR_API_KEY' });

async function rotateImage(imageUrl, angle) {
  try {
    const result = await qwenImageEdit.image.rotate({
      imageUrl: imageUrl,
      angle: angle, // 旋转角度,例如 90, 180, 270
    });
    console.log('旋转图像成功:', result.outputUrl);
    return result.outputUrl;
  } catch (error) {
    console.error('旋转图像失败:', error);
  }
}

// 示例用法
// rotateImage('https://example.com/your-image.jpg', 90);

1.8. 格式转换

将图像转换为不同的文件格式(例如 PNG 到 JPEG)。

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

const qwenImageEdit = new QwenImageEdit({ apiKey: 'YOUR_API_KEY' });

async function convertFormat(imageUrl, format) {
  try {
    const result = await qwenImageEdit.image.convertFormat({
      imageUrl: imageUrl,
      format: format, // 例如 'jpeg', 'png', 'webp'
    });
    console.log('格式转换成功:', result.outputUrl);
    return result.outputUrl;
  } catch (error) {
    console.error('格式转换失败:', error);
  }
}

// 示例用法
// convertFormat('https://example.com/your-image.png', 'jpeg');

2. 批量处理

同时处理多个图像,提高效率。

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

const qwenImageEdit = new QwenImageEdit({ apiKey: 'YOUR_API_KEY' });

async function batchProcessImages(imageUrls, operation) {
  try {
    const results = await qwenImageEdit.image.batchProcess({
      imageUrls: imageUrls,
      operation: operation, // 例如 { type: 'removeBackground' } 或 { type: 'resize', width: 200, height: 200 }
    });
    console.log('批量处理成功:', results);
    return results;
  } catch (error) {
    console.error('批量处理失败:', error);
  }
}

// 示例用法:批量移除背景
// batchProcessImages(
//   ['https://example.com/img1.jpg', 'https://example.com/img2.jpg'],
//   { type: 'removeBackground' }
// );

// 示例用法:批量调整大小
// batchProcessImages(
//   ['https://example.com/img3.jpg', 'https://example.com/img4.jpg'],
//   { type: 'resize', width: 150, height: 150, fit: 'contain' }
// );

3. 获取图像元数据

检索图像的详细信息,如尺寸、格式和EXIF数据。

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

const qwenImageEdit = new QwenImageEdit({ apiKey: 'YOUR_API_KEY' });

async function getImageMetadata(imageUrl) {
  try {
    const metadata = await qwenImageEdit.image.getMetadata({
      imageUrl: imageUrl,
    });
    console.log('图像元数据:', metadata);
    return metadata;
  } catch (error) {
    console.error('获取图像元数据失败:', error);
  }
}

// 示例用法
// getImageMetadata('https://example.com/your-image.jpg');

提示: 这些示例展示了 QwenImageEdit SDK 的核心功能。您可以根据自己的需求组合和扩展这些操作,以实现更复杂的图像编辑工作流。

动态文本生成

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

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 的熟悉逐渐探索更高级的功能。