Exemplos

Exemplos práticos e trechos de código para vários casos de uso

Exemplos Básicos

1. Edição Simples de Texto

Substituir Texto Existente

import { QwenImageEdit } from 'qwen-image-edit';

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

// Substituir texto em banner
const resultado = await editor.editText({
  imagem: './banner-original.jpg',
  prompt: 'Mudar "SALE" para "PROMOÇÃO"'
});

console.log('Banner atualizado:', resultado.imagemUrl);

Adicionar Novo Texto

// Adicionar texto com estilo específico
const resultado = await editor.editText({
  imagem: './produto.jpg',
  prompt: 'Adicionar "NOVO" em vermelho no canto superior direito',
  posicao: {
    x: 800,
    y: 50,
    alinhamento: 'direita'
  },
  cor: '#ff0000',
  tamanho: 'grande',
  fonte: 'Arial Bold'
});

2. Adição de Elementos

Adicionar Objetos Naturalmente

// Adicionar elemento que se integra naturalmente
const resultado = await editor.editElement({
  imagem: './sala-vazia.jpg',
  prompt: 'Adicionar uma planta verde no canto esquerdo',
  acao: 'adicionar',
  estilo: 'fotorrealista',
  fusao: 'natural'
});

Adicionar Marca d'Água

// Adicionar logo como marca d'água
const resultado = await editor.editElement({
  imagem: './foto-evento.jpg',
  prompt: 'Adicionar logo da empresa no canto inferior direito, semi-transparente',
  acao: 'adicionar',
  opacidade: 0.3,
  posicao: {
    x: 900,
    y: 650,
    alinhamento: 'direita'
  }
});

Exemplos Avançados

3. Transferência de Estilo

Aplicar Estilo Artístico

// Transformar foto em pintura
const resultado = await editor.transferStyle({
  imagem: './retrato.jpg',
  estilo: 'pintura a óleo impressionista',
  intensidade: 0.8,
  preservarDetalhes: true,
  paleta: ['#ff6b6b', '#4ecdc4', '#45b7d1', '#96ceb4']
});

Estilo Cinematográfico

// Aplicar filtro cinematográfico
const resultado = await editor.transferStyle({
  imagem: './paisagem.jpg',
  estilo: 'cinematográfico com tons azuis e laranjas',
  intensidade: 0.6,
  contraste: 1.2,
  saturacao: 1.1
});

4. Edição em Lote

Processar Múltiplas Imagens

// Função para processar lote de imagens
async function processarLote(imagens, prompt) {
  const resultados = [];
  
  // Processar com limite de concorrência
  const limite = 3;
  for (let i = 0; i < imagens.length; i += limite) {
    const lote = imagens.slice(i, i + limite);
    
    const promessas = lote.map(async (imagem) => {
      try {
        const resultado = await editor.editText({
          imagem,
          prompt
        });
        return { sucesso: true, imagem, resultado };
      } catch (error) {
        return { sucesso: false, imagem, erro: error.message };
      }
    });
    
    const resultadosLote = await Promise.all(promessas);
    resultados.push(...resultadosLote);
    
    // Pausa entre lotes para evitar rate limiting
    if (i + limite < imagens.length) {
      await new Promise(resolve => setTimeout(resolve, 1000));
    }
  }
  
  return resultados;
}

// Usar a função
const imagens = ['img1.jpg', 'img2.jpg', 'img3.jpg', 'img4.jpg'];
const resultados = await processarLote(imagens, 'Adicionar marca d\'água "CONFIDENCIAL"');

console.log(`Processadas ${resultados.filter(r => r.sucesso).length} de ${imagens.length} imagens`);

5. Edição Condicional

Editar Baseado no Conteúdo

// Primeiro analisar a imagem
const analise = await editor.analyzeImage({
  imagem: './documento.jpg',
  detectar: ['texto', 'objetos', 'cores']
});

// Editar baseado na análise
let resultado;
if (analise.texto.some(t => t.conteudo.includes('DRAFT'))) {
  // Se contém "DRAFT", substituir por "FINAL"
  resultado = await editor.editText({
    imagem: './documento.jpg',
    prompt: 'Mudar "DRAFT" para "FINAL"'
  });
} else if (analise.cores.dominantes.includes('#ff0000')) {
  // Se tem muito vermelho, suavizar as cores
  resultado = await editor.transferStyle({
    imagem: './documento.jpg',
    estilo: 'suavizar cores vermelhas',
    intensidade: 0.5
  });
} else {
  // Caso padrão: adicionar marca d'água
  resultado = await editor.editText({
    imagem: './documento.jpg',
    prompt: 'Adicionar "APROVADO" em verde no canto superior direito'
  });
}

Casos de Uso Específicos

6. Marketing e Publicidade

Localização de Campanhas

// Função para localizar campanha para diferentes mercados
async function localizarCampanha(imagemOriginal, idioma) {
  const traducoes = {
    'pt': {
      'SALE': 'PROMOÇÃO',
      '50% OFF': '50% DE DESCONTO',
      'LIMITED TIME': 'TEMPO LIMITADO'
    },
    'es': {
      'SALE': 'OFERTA',
      '50% OFF': '50% DE DESCUENTO',
      'LIMITED TIME': 'TIEMPO LIMITADO'
    },
    'fr': {
      'SALE': 'SOLDES',
      '50% OFF': '50% DE RÉDUCTION',
      'LIMITED TIME': 'TEMPS LIMITÉ'
    }
  };
  
  const textos = traducoes[idioma];
  let imagemAtual = imagemOriginal;
  
  // Aplicar todas as traduções
  for (const [original, traducao] of Object.entries(textos)) {
    const resultado = await editor.editText({
      imagem: imagemAtual,
      prompt: `Mudar "${original}" para "${traducao}" mantendo o mesmo estilo`,
      preservarEstilo: true
    });
    imagemAtual = resultado.imagemUrl;
  }
  
  return imagemAtual;
}

// Usar para diferentes mercados
const campanhaPortugues = await localizarCampanha('./campanha-en.jpg', 'pt');
const campanhaEspanhol = await localizarCampanha('./campanha-en.jpg', 'es');
const campanhaFrances = await localizarCampanha('./campanha-en.jpg', 'fr');

A/B Testing de Criativos

// Criar variações para teste A/B
async function criarVariacoes(imagemBase) {
  const variacoes = [
    {
      nome: 'urgencia',
      prompt: 'Adicionar "ÚLTIMAS HORAS" em vermelho piscante'
    },
    {
      nome: 'desconto',
      prompt: 'Destacar "70% OFF" em amarelo brilhante'
    },
    {
      nome: 'exclusividade',
      prompt: 'Adicionar "EXCLUSIVO" em dourado elegante'
    }
  ];
  
  const resultados = await Promise.all(
    variacoes.map(async (variacao) => {
      const resultado = await editor.editText({
        imagem: imagemBase,
        prompt: variacao.prompt
      });
      
      return {
        nome: variacao.nome,
        imagemUrl: resultado.imagemUrl
      };
    })
  );
  
  return resultados;
}

const variacoes = await criarVariacoes('./base-campanha.jpg');
console.log('Variações criadas:', variacoes.map(v => v.nome));

7. E-commerce

Preparação de Produtos

// Pipeline completo para imagens de produto
async function prepararImagemProduto(imagemOriginal, opcoes = {}) {
  let imagemAtual = imagemOriginal;
  
  // 1. Remover fundo se necessário
  if (opcoes.removerFundo) {
    const semFundo = await editor.editElement({
      imagem: imagemAtual,
      prompt: 'Remover o fundo, deixar apenas o produto',
      acao: 'remover'
    });
    imagemAtual = semFundo.imagemUrl;
  }
  
  // 2. Adicionar selo promocional
  if (opcoes.selo) {
    const comSelo = await editor.editText({
      imagem: imagemAtual,
      prompt: `Adicionar selo "${opcoes.selo}" no canto superior direito`,
      cor: opcoes.corSelo || '#ff0000',
      tamanho: 'medio'
    });
    imagemAtual = comSelo.imagemUrl;
  }
  
  // 3. Ajustar cores se necessário
  if (opcoes.ajustarCores) {
    const coresAjustadas = await editor.transferStyle({
      imagem: imagemAtual,
      estilo: 'cores mais vibrantes e atrativas',
      intensidade: 0.3,
      preservarDetalhes: true
    });
    imagemAtual = coresAjustadas.imagemUrl;
  }
  
  // 4. Redimensionar para diferentes tamanhos
  const tamanhos = {
    thumbnail: { largura: 300, altura: 300 },
    medio: { largura: 600, altura: 600 },
    grande: { largura: 1200, altura: 1200 }
  };
  
  const imagensRedimensionadas = {};
  for (const [nome, dimensoes] of Object.entries(tamanhos)) {
    const redimensionada = await editor.resizeImage({
      imagem: imagemAtual,
      dimensoes,
      manterAspecto: true,
      qualidade: 0.9
    });
    imagensRedimensionadas[nome] = redimensionada.imagemUrl;
  }
  
  return {
    imagemPrincipal: imagemAtual,
    tamanhos: imagensRedimensionadas
  };
}

// Usar o pipeline
const produtoPronto = await prepararImagemProduto('./produto-bruto.jpg', {
  removerFundo: true,
  selo: 'NOVO',
  corSelo: '#00ff00',
  ajustarCores: true
});

console.log('Produto preparado:', produtoPronto);

8. Criação de Conteúdo

Thumbnails para YouTube

// Criar thumbnail chamativo
async function criarThumbnailYoutube(imagemBase, titulo, estilo = 'dramatico') {
  let thumbnail = imagemBase;
  
  // 1. Aplicar estilo visual
  const estilos = {
    dramatico: 'alto contraste com cores vibrantes',
    minimalista: 'cores suaves e design limpo',
    energetico: 'cores neon e efeitos brilhantes'
  };
  
  const comEstilo = await editor.transferStyle({
    imagem: thumbnail,
    estilo: estilos[estilo],
    intensidade: 0.6
  });
  thumbnail = comEstilo.imagemUrl;
  
  // 2. Adicionar título principal
  const comTitulo = await editor.editText({
    imagem: thumbnail,
    prompt: `Adicionar "${titulo}" em letras grandes e chamativas no centro`,
    fonte: 'Impact',
    tamanho: 'extra-grande',
    cor: '#ffffff',
    contorno: '#000000',
    sombra: true
  });
  thumbnail = comTitulo.imagemUrl;
  
  // 3. Adicionar elementos de engagement
  const comElementos = await editor.editElement({
    imagem: thumbnail,
    prompt: 'Adicionar setas apontando para o conteúdo principal',
    acao: 'adicionar',
    cor: '#ffff00'
  });
  thumbnail = comElementos.imagemUrl;
  
  return thumbnail;
}

// Criar thumbnails para série de vídeos
const titulos = [
  'COMO FAZER EM 5 MINUTOS',
  'SEGREDO REVELADO',
  'VOCÊ NÃO VAI ACREDITAR'
];

const thumbnails = await Promise.all(
  titulos.map(titulo => 
    criarThumbnailYoutube('./frame-video.jpg', titulo, 'dramatico')
  )
);

console.log('Thumbnails criados:', thumbnails.length);

9. Automação de Fluxo de Trabalho

Sistema de Aprovação Automática

// Sistema que processa imagens baseado em regras
class ProcessadorImagemAutomatico {
  constructor(editor) {
    this.editor = editor;
    this.regras = [];
  }
  
  adicionarRegra(condicao, acao) {
    this.regras.push({ condicao, acao });
  }
  
  async processar(imagem) {
    // Analisar imagem
    const analise = await this.editor.analyzeImage({
      imagem,
      detectar: ['texto', 'objetos', 'cores', 'qualidade']
    });
    
    let imagemAtual = imagem;
    const acoes = [];
    
    // Aplicar regras
    for (const regra of this.regras) {
      if (regra.condicao(analise)) {
        const resultado = await regra.acao(imagemAtual, analise);
        imagemAtual = resultado.imagemUrl;
        acoes.push(resultado.descricao);
      }
    }
    
    return {
      imagemFinal: imagemAtual,
      acoesAplicadas: acoes,
      analiseOriginal: analise
    };
  }
}

// Configurar processador
const processador = new ProcessadorImagemAutomatico(editor);

// Regra: Se qualidade baixa, melhorar
processador.adicionarRegra(
  (analise) => analise.qualidade.pontuacao < 0.7,
  async (imagem) => {
    const resultado = await editor.enhanceImage({
      imagem,
      melhorias: ['nitidez', 'contraste', 'cores']
    });
    return {
      imagemUrl: resultado.imagemUrl,
      descricao: 'Qualidade melhorada'
    };
  }
);

// Regra: Se contém texto em inglês, traduzir
processador.adicionarRegra(
  (analise) => analise.texto.some(t => /^[a-zA-Z\s]+$/.test(t.conteudo)),
  async (imagem, analise) => {
    const textoIngles = analise.texto.find(t => /^[a-zA-Z\s]+$/.test(t.conteudo));
    const resultado = await editor.editText({
      imagem,
      prompt: `Traduzir "${textoIngles.conteudo}" para português`
    });
    return {
      imagemUrl: resultado.imagemUrl,
      descricao: `Texto traduzido: ${textoIngles.conteudo}`
    };
  }
);

// Usar o processador
const resultado = await processador.processar('./imagem-entrada.jpg');
console.log('Processamento concluído:', resultado.acoesAplicadas);

Otimização de Performance

10. Cache Inteligente

// Sistema de cache para operações repetidas
class CacheInteligente {
  constructor() {
    this.cache = new Map();
    this.estatisticas = {
      hits: 0,
      misses: 0
    };
  }
  
  gerarChave(imagem, operacao) {
    // Gerar hash baseado na imagem e operação
    const crypto = require('crypto');
    const hash = crypto.createHash('md5');
    hash.update(JSON.stringify({ imagem, operacao }));
    return hash.digest('hex');
  }
  
  async obter(chave) {
    if (this.cache.has(chave)) {
      this.estatisticas.hits++;
      return this.cache.get(chave);
    }
    this.estatisticas.misses++;
    return null;
  }
  
  definir(chave, valor, ttl = 3600000) { // 1 hora padrão
    this.cache.set(chave, valor);
    
    // Remover após TTL
    setTimeout(() => {
      this.cache.delete(chave);
    }, ttl);
  }
  
  obterEstatisticas() {
    const total = this.estatisticas.hits + this.estatisticas.misses;
    return {
      ...this.estatisticas,
      taxaAcerto: total > 0 ? (this.estatisticas.hits / total * 100).toFixed(2) + '%' : '0%'
    };
  }
}

// Editor com cache
class EditorComCache {
  constructor(editor) {
    this.editor = editor;
    this.cache = new CacheInteligente();
  }
  
  async editText(opcoes) {
    const chave = this.cache.gerarChave(opcoes.imagem, {
      tipo: 'editText',
      prompt: opcoes.prompt
    });
    
    // Verificar cache
    const resultadoCache = await this.cache.obter(chave);
    if (resultadoCache) {
      console.log('Resultado obtido do cache');
      return resultadoCache;
    }
    
    // Executar operação
    const resultado = await this.editor.editText(opcoes);
    
    // Salvar no cache
    this.cache.definir(chave, resultado);
    
    return resultado;
  }
  
  obterEstatisticasCache() {
    return this.cache.obterEstatisticas();
  }
}

// Usar editor com cache
const editorComCache = new EditorComCache(editor);

// Primeira chamada - será executada
const resultado1 = await editorComCache.editText({
  imagem: './teste.jpg',
  prompt: 'Adicionar "TESTE"'
});

// Segunda chamada - será obtida do cache
const resultado2 = await editorComCache.editText({
  imagem: './teste.jpg',
  prompt: 'Adicionar "TESTE"'
});

console.log('Estatísticas do cache:', editorComCache.obterEstatisticasCache());

11. Tratamento Robusto de Erros

// Sistema de retry com backoff exponencial
class EditorRobusto {
  constructor(editor, opcoes = {}) {
    this.editor = editor;
    this.maxTentativas = opcoes.maxTentativas || 3;
    this.delayBase = opcoes.delayBase || 1000;
    this.multiplicador = opcoes.multiplicador || 2;
  }
  
  async executarComRetry(operacao, ...args) {
    let ultimoErro;
    
    for (let tentativa = 1; tentativa <= this.maxTentativas; tentativa++) {
      try {
        return await operacao.call(this.editor, ...args);
      } catch (error) {
        ultimoErro = error;
        
        // Não fazer retry para alguns tipos de erro
        if (this.erroNaoRecuperavel(error)) {
          throw error;
        }
        
        if (tentativa < this.maxTentativas) {
          const delay = this.delayBase * Math.pow(this.multiplicador, tentativa - 1);
          console.log(`Tentativa ${tentativa} falhou, tentando novamente em ${delay}ms...`);
          await new Promise(resolve => setTimeout(resolve, delay));
        }
      }
    }
    
    throw new Error(`Operação falhou após ${this.maxTentativas} tentativas: ${ultimoErro.message}`);
  }
  
  erroNaoRecuperavel(error) {
    const codigosNaoRecuperaveis = [
      'AUTH_INVALID',
      'IMAGE_FORMAT_UNSUPPORTED',
      'IMAGE_TOO_LARGE',
      'PROMPT_INVALID'
    ];
    
    return codigosNaoRecuperaveis.includes(error.codigo);
  }
  
  async editText(opcoes) {
    return this.executarComRetry(this.editor.editText, opcoes);
  }
  
  async editElement(opcoes) {
    return this.executarComRetry(this.editor.editElement, opcoes);
  }
  
  async transferStyle(opcoes) {
    return this.executarComRetry(this.editor.transferStyle, opcoes);
  }
}

// Usar editor robusto
const editorRobusto = new EditorRobusto(editor, {
  maxTentativas: 3,
  delayBase: 1000,
  multiplicador: 2
});

try {
  const resultado = await editorRobusto.editText({
    imagem: './imagem.jpg',
    prompt: 'Adicionar texto'
  });
  console.log('Sucesso:', resultado.imagemUrl);
} catch (error) {
  console.error('Falha definitiva:', error.message);
}

Recursos Adicionais

📚 Documentação Relacionada

🛠️ Ferramentas e Recursos

💡 Dicas de Performance

  1. Use cache para operações repetidas
  2. Redimensione imagens grandes antes de processar
  3. Processe em lotes com limite de concorrência
  4. Implemente retry para operações críticas
  5. Monitore quotas para evitar interrupções

Pronto para mais? Explore os recursos avançados ou consulte a documentação completa da API.