API de geração de imagens do Gemini em Python: exemplo de código
Um passo a passo funcional em Python para a API de geração de imagens do Gemini, usando o modelo atual gemini-3.1-flash-image e a Interactions API. Gere sua primeira imagem, controle a proporção e a resolução, edite fotos, refaça chamadas que falharam e estime o custo real por imagem.
A maioria dos tutoriais de imagens do Gemini ainda chama gemini-2.5-flash-image, e a página de preços do Google lista esse modelo como descontinuado, com data de desativação em 2 de outubro de 2026. Essa data já passou, então os trechos baseados nele devem ser tratados como quebrados. Esta página usa o modelo atual, gemini-3.1-flash-image, e a Interactions API, que a própria documentação do Google agora apresenta em primeiro lugar.
Você vai sair de uma pasta vazia e chegar a um script funcional que gera uma imagem, controla o tamanho, edita uma foto existente, salva a saída mista de texto e imagem e sobrevive aos limites de taxa. Cada trecho é curto o bastante para colar em um arquivo e executar. Uma imagem 1K no modelo Flash padrão custa cerca de US$ 0,067, então os testes continuam baratos.
O que você precisa antes de programar
Três coisas separam você da sua primeira imagem: uma instalação recente do Python 3, uma credencial do Google AI Studio e um projeto com o faturamento ativado. A página de preços do Google não mostra nenhum nível gratuito para os modelos de geração de imagens do Gemini, então um projeto sem faturamento provavelmente será rejeitado na primeira chamada.
Instale o SDK
Um único pacote faz tudo:
pip install -U google-genai
A Interactions API precisa de google-genai2.3.0 ou mais recente, por isso a sinalização -U é importante. Execute pip show google-genai se algum trecho abaixo falhar com um erro de atributo em client.interactions.
Configure sua credencial
Crie uma credencial no Google AI Studio e depois exporte-a como variável de ambiente com exatamente o nome abaixo. O SDK lê essa variável sozinho, então seu script nunca precisa conter o segredo.
No PowerShell do Windows, a mesma linha é $env:GEMINI_API_KEY = "paste-your-credential-here".
💡 Nunca coloque a credencial em um script que vai para o Git. Mantenha-a em uma variável de ambiente ou em um arquivo .env que seu .gitignore já exclui.
Escolha um modelo
O Google agora lista quatro modelos de geração de imagens. Três são atuais, e um está aposentado.
ID do modelo
Tamanhos
Preço por imagem
Melhor para
gemini-3.1-flash-lite-image
Somente 1K
cerca de US$ 0,034
Trabalhos em massa, miniaturas
gemini-3.1-flash-image
0.5K, 1K, 2K, 4K
US$ 0,045, US$ 0,067, US$ 0,101, US$ 0,151
Escolha padrão para a maioria dos scripts
gemini-3-pro-image
1K, 2K, 4K
US$ 0,134 (1K e 2K), US$ 0,24 (4K)
Prompts complexos e com várias partes
gemini-2.5-flash-image
n/d
US$ 0,039
Aposentado, não use
Os preços vêm da página de preços do Google no momento em que este texto foi escrito. Confira novamente antes de uma execução grande.
Como escolher? Comece com gemini-3.1-flash-image. Ele é o único modelo atual que oferece os quatro tamanhos, então um mesmo caminho de código atende miniaturas e arquivos para impressão. Mude para o Flash Lite quando você gerar milhares de imagens pequenas e cada centavo por imagem contar. Recorra ao Pro quando um prompt tiver muitas partes, como um layout de cartaz com vários elementos rotulados, e um modelo mais barato continuar deixando detalhes de fora. Como os três modelos atuais compartilham a mesma forma de chamada, trocar de modelo depois significa editar uma única string.
Gere sua primeira imagem
Salve isto como first_image.py:
import base64
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.1-flash-image",
input="A photograph of a bowl of oranges on a linen cloth, soft window light",
)
with open("oranges.png", "wb") as f:
f.write(base64.b64decode(interaction.output_image.data))
Execute python first_image.py e um arquivo oranges.png aparece ao lado do script. Esse é todo o ciclo: prompt de entrada, string base64 na saída, bytes gravados em disco.
Quando você gerar mais de uma imagem, um nome de arquivo fixo sobrescreve o resultado anterior. Monte o nome a partir de um carimbo de data e hora, por exemplo f"image_{int(time.time())}.png", e cada execução deixa seu próprio arquivo. Assim você pode comparar uma dúzia de variações de um mesmo prompt lado a lado.
O que cada linha faz
genai.Client() cria um cliente e busca a credencial na variável de ambiente que você exportou antes, então nada sensível fica no arquivo.
client.interactions.create() envia o prompt e devolve um objeto Interaction que carrega um id, as etapas de saída e atalhos como output_image.
interaction.output_image.data guarda a imagem como uma string base64. Você precisa decodificá-la antes de gravar, senão o arquivo será texto, não uma imagem.
Escreva prompts que funcionam
O modelo responde melhor a descrições de cena do que a um amontoado de tags soltas. Um prompt que lê como a lista de planos de um fotógrafo dá mais controle do que uma lista de adjetivos.
Nomeie o sujeito e a ação. "Um padeiro polvilhando farinha sobre um pão" funciona melhor do que "padaria".
Descreva a luz. Luz de janela, céu nublado, hora dourada ou sol forte do meio-dia.
Acrescente lente e distância. "Retrato de 85mm, profundidade de campo rasa" ou "aérea ampla de 24mm".
Diga o que deixar de fora. Uma frase curta, como "sem texto na imagem".
💡 Guarde seus prompts em uma lista Python ou em um arquivo de texto. Quando um resultado surpreender, você pode mudar uma variável e comparar, o que é melhor do que reescrever de memória.
Controle o tamanho e a proporção
Tamanho e formato ficam dentro de um dicionário response_format. Isso confunde muita gente, porque o código antigo colocava as configurações de imagem em generation_config.
interaction = client.interactions.create(
model="gemini-3.1-flash-image",
input="A wide photograph of a coastal road at dawn, 35mm lens, film grain",
response_format={
"type": "image",
"mime_type": "image/jpeg",
"aspect_ratio": "16:9",
"image_size": "2K",
},
)
with open("coast.jpg", "wb") as f:
f.write(base64.b64decode(interaction.output_image.data))
Como o mime_type solicitado é JPEG, o arquivo recebe a extensão .jpg. Combine a extensão com o tipo que você pediu e seu visualizador de imagens nunca vai reclamar.
Proporções que você pode solicitar
A documentação do Google lista dez proporções: 1:1, 3:2, 2:3, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9 e 21:9.
Proporção
Uso típico
1:1
Fotos de perfil, miniaturas de produtos
4:5
Publicações no feed das redes sociais
9:16
Stories e miniaturas de vídeos verticais
16:9
Cabeçalhos de blog, miniaturas de vídeo
21:9
Banners ultralargos
3:2
Impressões de fotos clássicas
Escolha uma resolução
O valor image_size depende do modelo. O Flash Lite oferece somente 1K. O Flash oferece 0.5K, 1K, 2K e 4K. O Pro oferece 1K, 2K e 4K. Use K em maiúsculas no valor.
Uma regra simples mantém os custos sob controle: 1K para rascunhos, 2K para páginas web, 4K somente para impressão. Uma imagem 4K no Flash custa US$ 0,151 contra US$ 0,067 em 1K, cerca de 2,25 vezes mais, então o hábito de "sempre o máximo" se acumula rápido.
Edite uma foto com prompts de texto
O mesmo endpoint edita imagens. Em vez de uma string simples, input vira uma lista que mistura blocos de texto e blocos de imagem. A imagem viaja como string base64 com seu tipo MIME.
import base64
from google import genai
client = genai.Client()
with open("portrait.png", "rb") as f:
encoded = base64.b64encode(f.read()).decode("utf-8")
interaction = client.interactions.create(
model="gemini-3.1-flash-image",
input=[
{
"type": "text",
"text": "Replace the background with a sunlit brick wall. Keep the person unchanged.",
},
{"type": "image", "data": encoded, "mime_type": "image/png"},
],
)
with open("portrait_edit.png", "wb") as f:
f.write(base64.b64decode(interaction.output_image.data))
Observe a redação do prompt de edição. Ele diz o que muda (o fundo) e o que permanece (a pessoa). Sem a segunda metade, o modelo fica livre para redesenhar o quadro inteiro.
Encadeie edições em uma conversa
Você não precisa reenviar a imagem a cada ajuste. Passe o id da interação anterior e o modelo lembra da imagem que acabou de criar:
second = client.interactions.create(
model="gemini-3.1-flash-image",
input="Make the light warmer, like late afternoon.",
previous_interaction_id=interaction.id,
response_format={
"type": "image",
"mime_type": "image/jpeg",
"aspect_ratio": "4:5",
"image_size": "2K",
},
)
Mantenha a mesma proporção da primeira imagem, senão o modelo pode cortar ou estender a cena. Armazene cada interaction.id no seu banco de dados e você pode voltar a qualquer etapa anterior de uma sessão, o que é útil em trabalhos para clientes, em que "volte para a versão dois" aparece com frequência.
Leia respostas mistas e adicione busca
Às vezes o modelo responde com uma frase de texto e uma imagem. O atalho output_image serve para scripts simples, mas um auxiliar que percorre a lista steps cuida de todos os casos:
def save_outputs(interaction, prefix="gemini", ext="png"):
saved = []
for step in interaction.steps:
if step.type != "model_output":
continue
for block in step.content:
if block.type == "text":
print(block.text)
elif block.type == "image":
path = f"{prefix}_{len(saved) + 1}.{ext}"
with open(path, "wb") as f:
f.write(base64.b64decode(block.data))
saved.append(path)
return saved
A função devolve uma lista de caminhos de arquivo. Uma lista vazia significa que o modelo enviou somente texto, o que não é uma exceção, então verifique isso antes de presumir que um arquivo existe.
Ancore prompts com busca
Algumas imagens dependem de fatos que mudam todo dia: um gráfico do tempo, um placar, um gráfico de preços. Ative a Pesquisa Google e o modelo pode buscar dados atualizados antes de desenhar:
interaction = client.interactions.create(
model="gemini-3.1-flash-image",
input="Create an infographic of this week's weather in Chicago",
tools=[{"type": "google_search"}],
generation_config={"thinking_level": "high"},
)
A configuração thinking_level aceita "minimal" ou "high". Use minimal quando a velocidade importar e o layout for simples. Use high quando o prompt pedir um layout estruturado com várias partes.
💡 Toda imagem devolvida pela API traz uma marca d'água SynthID, uma marca invisível que o Google adiciona para que a imagem possa ser identificada como gerada por IA. Você não precisa adicionar uma por conta própria.
Trate os erros antes da produção
Chamadas de imagem costumam demorar mais do que chamadas de texto, e rajadas de requisições podem acionar limites de taxa. Um pequeno wrapper de repetição poupa você da maior parte dos problemas. Ele repete em caso de HTTP 429, 500 e 503 e espera mais a cada falha:
import time
def generate_with_retry(prompt, retries=4, **kwargs):
for attempt in range(retries):
try:
return client.interactions.create(
model="gemini-3.1-flash-image",
input=prompt,
**kwargs,
)
except Exception as exc:
status = getattr(exc, "status_code", None) or getattr(exc, "code", None)
if status not in (429, 500, 503) or attempt == retries - 1:
raise
time.sleep(2 ** attempt)
Dependendo da versão do SDK, o status HTTP fica em status_code ou em code, então o auxiliar verifica os dois. Qualquer coisa que não possa ser repetida, como uma requisição inválida, é lançada imediatamente para que você veja a mensagem real.
Para processar uma lista de prompts, execute poucos de cada vez:
from multiprocessing.pool import ThreadPool
prompts = ["A bowl of oranges", "A lighthouse at dusk", "A forest road in fog"]
with ThreadPool(4) as pool:
results = pool.map(generate_with_retry, prompts)
Comece com quatro workers. Se o auxiliar de repetição continuar disparando, reduza para dois antes de aumentar qualquer cota.
Prompts recusados exigem outro hábito. A documentação do Google observa que configurações de segurança personalizadas não são suportadas na Interactions API, então você não pode afrouxar os filtros pelo código. Quando uma resposta voltar com texto e sem imagem, registre o prompt e o texto e depois reescreva o prompt com uma descrição mais calma e mais concreta. Repetir exatamente o mesmo prompt raramente muda a resposta e só consome tempo.
3 erros comuns
Chamar um modelo aposentado. Qualquer trecho com gemini-2.5-flash-image precisa ter a string do modelo trocada por uma atual.
Colocar aspect_ratio em generation_config. Ele pertence a response_format, junto de image_size.
Gravar a string base64 em disco. Execute sempre base64.b64decode() antes, senão o arquivo não abre.
Se você ainda tem código antigo que chama generate_content, o Google diz que essa API continua suportada e agora está marcada como legada. Para projetos novos, a Interactions API é a que a documentação do Google recomenda.
Acompanhe os custos
Os custos crescem com o volume, então faça as contas antes de um loop grande. Quinhentas imagens 2K no Flash custam 500 x US$ 0,101, o que dá US$ 50,50. O Google também oferece preço em lote, por cerca de metade da tarifa padrão, para trabalhos que podem esperar:
Resolução
Padrão
Lote
0.5K
US$ 0,045
US$ 0,022
1K
US$ 0,067
US$ 0,034
2K
US$ 0,101
US$ 0,050
4K
US$ 0,151
US$ 0,076
As mesmas 500 imagens em 2K pelo lote custam cerca de US$ 25. Se ninguém estiver esperando o resultado, como uma atualização noturna de catálogo, o lote é o caminho mais barato.
Use o Nano Banana Pro no PicassoIA
Nem toda imagem precisa de um script. Se você quer testar um prompt antes de gastar créditos da API, ou passar o trabalho para um colega que não programa em Python, o Nano Banana Pro no PicassoIA é uma forma sem código de obter saída de até 4K da mesma família de modelos do Google.
Escreva seu prompt. Use o mesmo estilo de lista de planos de antes: sujeito, luz, lente.
Adicione imagens de referência (opcional). O campo Image Input aceita até 14 imagens que orientam estilo, composição ou sujeito.
Escolha uma proporção. Selecione entre 11 predefinições, incluindo 16:9, 9:16, 4:5, 21:9 e match_input_image.
Escolha uma resolução.1K, 2K (o padrão) ou 4K.
Escolha um formato. JPG (o padrão) ou PNG.
Defina o filtro de segurança.block_only_high é o padrão e o mais permissivo; block_low_and_above é o mais rigoroso.
Gere e baixe. Execute novamente com um prompt ajustado para comparar versões.
Relacione as configurações da API aos campos da página
Se você faz protótipos na página e depois passa para o código, as configurações quase se alinham uma a uma:
Campo no PicassoIA
Equivalente na API Python
Prompt
input (bloco de texto)
Image Input
input (blocos de imagem, base64)
aspect_ratio
response_format["aspect_ratio"]
resolution
response_format["image_size"]
output_format
response_format["mime_type"]
A família Google no PicassoIA é mais ampla do que um único modelo. O Nano Banana cuida de edições rápidas, o Nano Banana 2 Lite prioriza velocidade, e o Imagen 4 e o Imagen 4 Ultra focam em detalhes fotorrealistas. Rodar o mesmo prompt em dois deles leva um minuto e mostra qual estilo combina com seu projeto antes de você escrever uma única linha de código de integração.
Crie suas próprias imagens hoje
Agora você tem todas as peças: uma instalação funcional, a primeira imagem, controle de tamanho e proporção, edições, uma forma segura de ler saídas mistas, um wrapper de repetição e uma estimativa de custo em que você pode confiar. Escolha um trabalho pequeno, como um cabeçalho de blog ou a miniatura de um produto, e execute do início ao fim ainda esta tarde.
Se você prefere ver resultados antes de abrir um terminal, abra o Picasso IA, escolha um modelo como o Nano Banana Pro e digite o prompt que você acabou de escrever para o seu script. Teste três variações, mude a proporção e compare. O melhor prompt que você encontrar ali vai direto para o código Python acima.
Esse ciclo, testar na página e lançar em código, é o caminho mais rápido para definir um visual sem pagar por cada experimento. Abra o Picasso IA, rode seu primeiro prompt e veja o que você pode criar antes que a tarde termine.