Como gerar variações de foto de produto em lote com a API do Gemini?

Para gerar imagens em lote com a API do Gemini, o caminho é um script que percorre uma lista de produtos, aplica o mesmo bloco de prompt e chama client.interactions.create() com um modelo da família Nano Banana. A imagem volta em base64 em interaction.output_image.data, você decodifica, salva com nome previsível vindo do SKU e registra falhas em log em vez de abortar o lote. Em 1K, o gemini-3.1-flash-lite-image custa US$ 0,0336 por imagem e o gemini-3.1-flash-image US$ 0,067. Para volume grande, a própria documentação recomenda a Batch API com arquivo JSONL
Repetir o mesmo prompt de foto de produto 80 vezes no chat, trocando só o nome do item, é o tipo de trabalho que ninguém deveria estar fazendo na mão
Se o cenário, a luz e o fundo são sempre os mesmos, o que muda ali é dado, não criatividade
Neste post eu monto o roteiro de um script que percorre uma lista de produtos, aplica um bloco de prompt único, salva cada arquivo com nome previsível e registra as falhas em log, tudo pela API do Gemini (Nano Banana é o nome das capacidades nativas de geração de imagem do Gemini, e é assim que a documentação batiza essa linha de modelos)
A parte de COMO descrever cena, luz e fundo já está resolvida nos prompts de foto de produto no Gemini, e é de lá que sai o texto que o script vai repetir
Aqui a decisão é outra: qual modelo, como o retorno chega, qual proporção o modelo aceita, qual o limite de taxa e quanto custa cada imagem 🙂
O que você precisa antes de rodar o script
A lista é curta, e vale conferir cada item antes de disparar volume:
- SDK Python do Google, porque toda a chamada sai de
from google import genaie de umclient = genai.Client() - Uma chave de API do Gemini configurada no ambiente, pra o client subir sem você colar credencial no meio do código
- Conta de faturamento ativa vinculada, se o objetivo for volume: o Tier 1 do Gemini API exige isso, enquanto o Free tier não tem limite de gasto aplicável
- Atenção ao teto de 20MB por requisição, que conta o prompt de texto, as instruções de sistema e os bytes inline juntos (isso pesa quando você manda foto de referência do produto dentro da chamada)
E agora o aviso que evita frustração: os valores de RPM (requisições por minuto) e TPM (tokens por minuto) por modelo não são publicados na documentação
A API combina RPM, TPM e limites baseados em gasto, e esses limites mudam automaticamente conforme o tier e o status da conta
A documentação manda o dev conferir os limites por modelo na página de Rate Limit do Google AI Studio, dentro da própria conta
Ou seja: o número que vale pra você é o que está lá, não o que um blog aleatório chutou
Formação Claude Code
Domine Claude Code do absoluto zero até o avançado
- 120 aulas
- 4 projetos
- 9h 45min
Passo a passo: script de variações de foto de produto em lote
A ideia do script é boba de propósito: dado entra, prompt padroniza, arquivo sai com nome que você consegue prever
Se você já mexeu com qualquer rotina de importação de CSV, o desenho é o mesmo, só que a "transformação" no meio é uma chamada de API que devolve imagem
- Monte a lista de produtos e UM bloco de prompt parametrizado
A fonte de dados pode ser uma lista de dicionários mesmo, com nome, SKU e descrição curta
O prompt fica em uma única string com placeholders, e é isso que garante padrão visual entre 200 imagens
PROMPT = (
"Foto de produto de {nome}, {descricao}, "
"mesmo cenário, mesma luz e mesmo fundo para toda a série"
)
produtos = [
{"sku": "CAN-001", "nome": "caneca branca 300ml", "descricao": "cerâmica lisa"},
{"sku": "CAN-002", "nome": "caneca preta 300ml", "descricao": "cerâmica fosca"},
]
O erro comum deste passo: reescrever a redação do prompt item a item, "melhorando" no meio do caminho
Aí o lote sai bonito e inconsistente, que é o pior dos mundos pra catálogo
- Chame a geração pela Interactions API
Na Interactions API do SDK Python, a geração de imagem sai de client.interactions.create(), passando o modelo e o prompt no parâmetro input
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.1-flash-image",
input=PROMPT.format(**produto),
)
O erro comum deste passo: trocar de modelo no meio do lote
A família tem três modelos ativos na documentação de geração de imagem: gemini-3.1-flash-image (Nano Banana 2), gemini-3.1-flash-lite-image (Nano Banana 2 Lite) e gemini-2.5-flash-image (Nano Banana, descrito como o pioneiro legado da série)
E sim, o nome confunde: Nano Banana é o guarda-chuva das capacidades nativas de geração de imagem do Gemini, e ao mesmo tempo, dentro dessa lista de modelos, "Nano Banana" sem número é o apelido que a documentação usa pro 2.5 legado
Eles têm capacidades e custos diferentes, então comparar imagem do item 12 com a do item 130 geradas por modelos distintos não diz nada
- Defina o
response_formatcom tipo, proporção e tamanho
A requisição aceita um response_format que define o tipo de saída, a proporção e o tamanho da imagem
interaction = client.interactions.create(
model="gemini-3.1-flash-image",
input=PROMPT.format(**produto),
response_format={
"type": "image",
"aspect_ratio": "16:9",
"image_size": "4K",
},
)
O erro comum deste passo: pedir proporção que o modelo escolhido não suporta
O gemini-3.1-flash-lite-image suporta uma lista fechada: 1:1, 3:2, 2:3, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9 e 21:9
O gemini-3.1-flash-image acrescenta as extremas 1:4, 4:1, 1:8 e 8:1, e entrega saída até 4K
- Decodifique o base64 e salve em disco
A imagem gerada volta como dado base64 no objeto de resposta, em interaction.output_image.data
import base64
conteudo = base64.b64decode(interaction.output_image.data)
with open(nome_arquivo, "wb") as arquivo:
arquivo.write(conteudo)
Se o seu código ainda roda na API legada de generateContent, o caminho é outro: as partes de imagem da resposta são identificadas por part.inline_data, e os bytes saem de base64.b64decode(part.inline_data.data)
O erro comum deste passo: tentar jogar o objeto de resposta direto num arquivo .png
Dá arquivo corrompido, e você perde meia hora achando que o problema é o prompt
- Nomeie o arquivo a partir dos campos da própria lista
Nome previsível é o que te deixa rodar de novo só o que faltou
nome_arquivo = f"{produto['sku']}_{variacao}_{aspect_ratio.replace(':', 'x')}_{image_size}.png"
# CAN-001_fundo-claro_16x9_4K.png
Com SKU, variação, proporção e tamanho no nome, o script consegue checar se o arquivo já existe e pular
O erro comum deste passo: nome com timestamp aleatório
Fica impossível saber o que já foi gerado, e no reprocessamento você paga de novo por imagem que já tinha 😛
- Registre as falhas em log, sem abortar o lote
Cada item entra num try, e o que quebrar vai pro log com a chave do item e o erro
for produto in produtos:
try:
gerar_imagem(produto)
except Exception as erro:
with open("falhas.log", "a", encoding="utf-8") as log:
log.write(f"{produto['sku']}\t{erro}\n")
O erro comum deste passo: deixar a exceção derrubar a execução no item 40 de 200
Você volta do café e encontra o lote parado, sem saber quais dos 160 restantes já tinham ido
Quando usar a Batch API em vez de paralelizar chamadas
Esse é o ponto onde a maioria decide errado, porque o instinto é abrir threads
A documentação de geração de imagem recomenda explicitamente a Batch API pra quem precisa gerar muitas imagens com Nano Banana, trocando turnaround de até 24 horas por limites de taxa maiores
A Batch API processa as requisições de forma assíncrona a 50% do custo padrão, com prazo alvo de 24 horas (frequentemente mais rápido)
- Escolha o formato de envio
São dois: requisições inline (uma lista de objetos GenerateContentRequest, indicada pra lotes com menos de 20MB no total) ou arquivo JSONL
Pra lotes grandes e pra geração de imagem, o recomendado é o JSONL
- Escreva uma linha por requisição, com chave definida por você
Cada linha do JSONL é um objeto JSON com uma chave definida pelo usuário e um GenerateContentRequest válido
{"key": "CAN-001_fundo-claro_16x9_4K", "request": {"contents": [{"parts": [{"text": "Foto de produto de caneca branca 300ml..."}]}]}}
{"key": "CAN-002_fundo-claro_16x9_4K", "request": {"contents": [{"parts": [{"text": "Foto de produto de caneca preta 300ml..."}]}]}}
Percebe o que essa chave faz? Ela é exatamente o nome de arquivo previsível do passo 5
Quando o job termina, você casa retorno com arquivo sem inventar mapeamento nenhum, é só ler a chave
Um aviso honesto aqui: a estrutura exata pra configurar response_format, aspect_ratio e image_size dentro da linha do JSONL não está confirmada nos meus registros, então confira esse campo na documentação antes de gerar o arquivo inteiro
Preferi omitir o passo a ensinar o campo errado e te fazer refazer 500 linhas
- Reaproveite conteúdo em cache, se fizer sentido
A Batch API suporta cache de contexto dentro das requisições do lote, informando o resource name em cached_content na configuração de cada requisição
- Sobre paralelismo: consulte o seu limite antes
Como os valores de RPM e TPM por modelo não são publicados na documentação, qualquer "use N threads" que você ler por aí é chute
A decisão de rodar chamadas em paralelo depende do que a página de Rate Limit do Google AI Studio mostra na sua conta, no seu tier
Então o caminho seguro é: olhar o limite real, ou simplesmente mandar pro Batch e ir tomar um café ☕
Custo por imagem: quanto sai um lote de 50, 200 e 500 fotos
A imagem de saída é cobrada por tokens, e a documentação publica a equivalência por resolução, o que dá pra transformar em conta de lote antes de rodar
Conversão única deste post: US$ 1 = R$ 5,16 (dólar à vista em 14/09/2026)
| Modelo e resolução | Tokens de saída | US$ por imagem | Lote de 50 | Lote de 200 | Lote de 500 | Lote de 500 em R$ |
|---|---|---|---|---|---|---|
| gemini-3.1-flash-lite-image 1K | a partir de 1.120 | 0,0336 | 1,68 | 6,72 | 16,80 | 86,69 |
| gemini-3.1-flash-image 0,5K (512px) | 747 | 0,045 | 2,25 | 9,00 | 22,50 | 116,10 |
| gemini-3.1-flash-image 1K (1024×1024) | 1.120 | 0,067 | 3,35 | 13,40 | 33,50 | 172,86 |
| gemini-3.1-flash-image 2K (2048×2048) | 1.680 | 0,101 | 5,05 | 20,20 | 50,50 | 260,58 |
| gemini-3.1-flash-image 4K (4096×4096) | 2.520 | 0,151 | 7,55 | 30,20 | 75,50 | 389,58 |
| gemini-3-pro-image-preview 1K e 2K | não detalhado aqui | 0,134 | 6,70 | 26,80 | 67,00 | 345,72 |
| gemini-3-pro-image-preview 4K | não detalhado aqui | 0,24 | 12,00 | 48,00 | 120,00 | 619,20 |
Detalhes que sustentam a tabela, todos da tabela oficial de preços: no Gemini Developer API, a saída de imagem do gemini-3.1-flash-lite-image em 1K parte de 1.120 tokens com preço de saída de imagem de US$ 30 por 1 milhão de tokens, e o gemini-3-pro-image-preview cobra US$ 2 por 1 milhão de tokens de entrada de texto
Sobre o Batch: a regra dos 50% do custo padrão está documentada como característica da Batch API, porém a tabela de preços não traz o valor por imagem já com esse desconto aplicado sobre tokens de imagem
Por isso a tabela acima está em preço cheio, que é o pior cenário
E tem outro freio que muita gente esquece: os limites por gasto
Tier 1 tem limite de US$ 10 por 10 minutos, Tier 2 vai a US$ 50 por 10 minutos e Tier 3 a US$ 200 por 10 minutos
Isso não muda o custo total do lote, muda a VELOCIDADE com que você consegue queimar ele
Qual modelo escolher para lote de foto de produto?
Padrão de lote: gemini-3.1-flash-lite-image
A documentação descreve ele como o modelo de imagem mais rápido e mais barato da linha, orientado a escala, e pra entrega 1K de catálogo e marketplace isso é exatamente o que o trabalho pede
Sobe pro gemini-3.1-flash-image quando o lote precisa de 4K, de renderização de texto (rótulo, embalagem, selo) ou daquelas proporções extremas 1:4, 4:1, 1:8 e 8:1
Ele é posicionado como o workhorse generalista da família, equilibrando velocidade com 4K, conhecimento de mundo e texto
O gemini-3-pro-image-preview entra só quando o custo por imagem mais alto se justifica em peça específica, porque num lote de 500 a diferença deixa de ser detalhe
O gemini-2.5-flash-image segue listado, descrito como o pioneiro legado da série
E o recado de migração: os modelos Imagen estão deprecados para geração de imagem no Gemini API, com desligamento em 17 de agosto de 2026 e recomendação oficial de migrar para Nano Banana
Se tem script antigo apontando pra Imagen, essa fila anda agora, não em agosto
Uma coisa precisa ficar explícita: essa escolha acima é leitura de documentação, não resultado de teste comparativo nosso
O comparativo visual, em cima do SEU produto, quem faz é você com um lote pequeno
Três cenários em que o lote compensa (e um em que não)
Catálogo de e-commerce com dezenas de SKUs: mesmo cenário, mesma luz, mesmo fundo, muda o produto
É o caso perfeito, porque o valor todo está na consistência, e consistência é o que um bloco de prompt fixo entrega melhor que a mão humana
Variação de proporção do mesmo produto: feed, story e banner saem da mesma lista, só trocando o aspect_ratio entre os suportados pelo modelo escolhido
O nome de arquivo já carrega a proporção, então o pessoal de social pega a pasta e monta o calendário sozinho
Refresh sazonal de fundo: mesma lista, mesmo esqueleto de prompt, muda só o trecho de cenário
Janeiro vira verão, novembro vira Black Friday, e o catálogo inteiro se atualiza sem sessão de foto
Agora o contracaso, porque nem tudo é lote: se você precisa de 3 ou 4 imagens, ou de uma peça hero que vai receber ajuste fino a cada tentativa, o script não paga a montagem
Ajuste fino é conversa, e conversa é chat: você olha, corrige uma frase, olha de novo
Depois que a imagem final está fechada, aí sim pode valer dar movimento nela, tipo transformar a foto do produto em vídeo com movimento de câmera
Conclusão
Lote bom se resume a três controles, e nenhum deles é criativo:
Nome de arquivo previsível, pra saber o que já existe e reprocessar só o que faltou
Log de falhas, pra o item 40 não derrubar os outros 160
Custo calculado antes de rodar, com a tabela de preços na frente e não depois da fatura
Próximo passo prático: abra a página de Rate Limit do Google AI Studio na sua conta pra ver os limites reais, rode o script num lote pequeno de teste (5 itens resolvem), e migre pro JSONL na Batch API quando o volume crescer
E se o resultado sair certinho no formato mas sem graça na foto, o problema não está no script, está no texto que ele repete: vale voltar no post de prompts e refinar o bloco de cenário, luz e fundo antes de disparar 500 imagens iguais…
até o próximo post! 😀
Perguntas frequentes
Quanto custa gerar fotos de produto em lote com o gemini-3.1-flash-image em 1K?
No Gemini Developer API, a imagem de saída é cobrada por tokens: cada imagem 1024×1024 do gemini-3.1-flash-image equivale a 1.120 tokens, com preço publicado de US$ 0,067 por imagem. Pra saber o custo do seu lote, multiplique esse valor pela quantidade de itens antes de rodar, e a tabela do post já traz lotes de 50, 200 e 500 em preço cheio. Se você usar a Batch API, o processamento é assíncrono e sai a 50% do custo padrão.
Vale a pena usar a Batch API pra gerar fotos de produto em vez da Interactions API direto?
Se o volume é grande, sim: a documentação recomenda explicitamente a Batch API pra quem precisa gerar muitas imagens com Nano Banana, trocando prazo por limites de taxa maiores. O processamento é assíncrono, custa metade do preço padrão e tem prazo alvo de 24 horas, frequentemente mais rápido que isso. Pra lotes grandes, o formato recomendado é o arquivo JSONL, com uma linha por requisição.
Qual a diferença de custo entre o gemini-3.1-flash-image e o gemini-3.1-flash-lite-image em lote?
O gemini-3.1-flash-lite-image sai mais barato: uma imagem 1K custa US$ 0,0336, contra US$ 0,067 do gemini-3.1-flash-image na mesma resolução. Em compensação, o Lite tem uma lista fechada de proporções (1:1, 3:2, 2:3, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9 e 21:9) e não chega nas proporções extremas nem na saída 4K que o modelo generalista oferece. A escolha depende se o catálogo precisa de proporção incomum ou resolução mais alta.
Dá pra gerar imagens em 4K num lote grande sem estourar o orçamento?
Dá, mas o custo por imagem sobe: no gemini-3.1-flash-image, uma imagem 4K equivale a 2.520 tokens e custa US$ 0,151, contra US$ 0,067 em 1K. A Batch API processa a 50% do custo padrão, então ela é o caminho natural quando o lote é grande e o prazo de até 24 horas não atrapalha. Antes de disparar, calcule o total multiplicando o preço por imagem pela quantidade de SKUs, porque em 4K a diferença aparece rápido.
Preciso de conta de faturamento pra rodar um script de geração de imagem em lote?
Só se o volume exigir sair do Free tier, que não tem limite de gasto aplicável mas também não oferece os limites de taxa maiores dos tiers pagos. O Tier 1 exige conta de faturamento ativa vinculada e tem teto de US$ 10 por 10 minutos, enquanto o Tier 2 sobe pra US$ 50 e o Tier 3 pra US$ 200 no mesmo intervalo. Os limites de RPM e TPM por modelo, porém, só aparecem na página de Rate Limit do Google AI Studio, dentro da sua própria conta.
Posso usar o Imagen do Google pra gerar as variações de foto de produto em lote?
Não é recomendado começar um script novo com Imagen: os modelos foram descontinuados para geração de imagem no Gemini API, com desligamento marcado para 17 de agosto de 2026. A recomendação oficial é migrar pra família Nano Banana, que é justamente o que este script usa. Então o caminho certo já é o gemini-3.1-flash-image ou o gemini-3.1-flash-lite-image, dependendo do equilíbrio entre custo e proporção que você precisa.
Formações
Formação Vibe Coding
Do Prompt ao Produto: Crie Software Real com IA
- 474 aulas
- 20 projetos
- 39h 27min
Blog | Mais populares
Gemini Pro vale a pena para estudante? O que muda de verdade na rotina de estudo
Gemini Pro estudante: veja o preço atual do Google AI Pro, o que muda na rotina de estudo e se vale migrar do plano gratuito para universitários em 2026.
Gemini e NotebookLM: qual a relação entre as duas ferramentas de IA do Google?
Gemini e NotebookLM viraram uma dupla: em julho/2026 o Google renomeou o NotebookLM para Gemini Notebook. Veja a diferença e quando usar cada um.
Como excluir sua conta do Gemini e o que acontece com seus dados
Como excluir conta Gemini: apague só o histórico ou encerre a Conta Google inteira. Saiba exatamente o que acontece com seus dados antes de decidir.
