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
- Início Rápido - Configure em minutos
- Referência da API - Documentação completa
- Configuração - Otimizações avançadas
- Solução de Problemas - Resolva problemas
- Funcionalidades Avançadas - Recursos avançados
🛠️ Ferramentas e Recursos
- Playground Online: playground.qwen.com
- Postman Collection: Download
- Exemplos no GitHub: github.com/qwen/examples
- Discord da Comunidade: discord.gg/qwen
💡 Dicas de Performance
- Use cache para operações repetidas
- Redimensione imagens grandes antes de processar
- Processe em lotes com limite de concorrência
- Implemente retry para operações críticas
- Monitore quotas para evitar interrupções
Pronto para mais? Explore os recursos avançados ou consulte a documentação completa da API.