API de geração de imagens da OpenAI em Python: exemplo passo a passo
Envie um prompt pelo Python, receba uma imagem em base64 e salve no disco. Este tutorial usa os modelos GPT Image atuais e mostra como tamanho, qualidade e formato mudam o resultado, depois acrescenta edições com máscara, prévias em streaming, lotes assíncronos e um rastreador de custos.
A maioria dos tutoriais sobre o endpoint de imagens da OpenAI para em "aqui está uma URL". Isso funcionava com o DALL-E. Não funciona com os modelos GPT Image, que devolvem dados em base64 e nada além disso, então o script que as pessoas copiam primeiro muitas vezes quebra em result.data[0].url. Este tutorial começa com um script que roda e depois o expande com tamanhos, níveis de qualidade, edições baseadas em máscara, prévias em streaming, lotes assíncronos e um pequeno rastreador de custos.
Os parâmetros, os nomes dos modelos e os preços abaixo vêm da documentação atual de geração de imagens da OpenAI e da página de preços, consultadas em 2026-10-06. Quando um número pode mudar, o texto informa isso.
Antes de escrever qualquer código
Três coisas precisam estar prontas antes que a primeira requisição funcione: um nome de modelo, o SDK instalado e uma organização verificada na OpenAI. Esta última é a que mais dá problema para as contas novas, porque os modelos GPT Image devolvem erro de acesso até que a verificação seja feita nas configurações do console de desenvolvedor.
Escolha um modelo
Estes são os modelos GPT Image que a OpenAI precifica hoje. Todos os cinco também rodam no PicassoIA, o que é útil para testar um prompt antes de escrever qualquer código.
Crie uma chave secreta de projeto no painel da OpenAI e depois a exponha como variável de ambiente. O SDK a lê automaticamente, então a chave nunca aparece no seu arquivo de código.
# macOS / Linux
export OPENAI_API_KEY="sk-..."
# Windows PowerShell
$env:OPENAI_API_KEY = "sk-..."
💡 Dica: mantenha a chave fora de notebooks que você pretende compartilhar e fora do histórico do git. Se ela vazar, revogue-a no painel e crie uma nova.
Sua primeira imagem em Python
O script mínimo
Aqui está o script completo. Execute-o e um PNG aparece ao lado do script.
import base64
from pathlib import Path
from openai import OpenAI
client = OpenAI()
result = client.images.generate(
model="gpt-image-2.5-flare",
prompt="A ceramic bowl of ripe peaches on a linen cloth, soft window light, 50mm photograph",
size="1536x1024",
quality="medium",
)
image_bytes = base64.b64decode(result.data[0].b64_json)
Path("peaches.png").write_bytes(image_bytes)
Quatro argumentos fazem o trabalho. model escolhe o motor, prompt descreve a imagem, size define as dimensões em pixels e quality troca velocidade e custo por detalhe. Todo o resto tem um padrão sensato, e o formato de saída é PNG a menos que você peça outro.
Escreva prompts que se sustentem
Um prompt que funciona em uma demonstração pode desmoronar em um loop de cinquenta imagens. Quatro hábitos mantêm os resultados estáveis:
Comece pelo sujeito, depois pelo cenário, pela luz e pela lente. "Uma tigela de cerâmica com pêssegos maduros sobre um pano de linho, luz suave de janela vinda da esquerda, fotografia 50mm" vence uma lista de adjetivos.
Coloque entre aspas qualquer texto que deva aparecer na imagem, e mantenha-o em uma ou duas palavras.
Diga o que evitar em termos positivos. "Parede branca lisa" funciona melhor do que "sem bagunça".
Mude uma coisa por execução. Se você alterar o sujeito, a luz e o tamanho ao mesmo tempo, não saberá qual mudança ajudou.
Por que a resposta vem em base64
Os modelos GPT Image sempre devolvem base64. A opção response_format="url", que o DALL-E aceitava, não é suportada, então result.data[0].url não existe e a imagem em si chega dentro de b64_json. Três hábitos decorrem disso:
Decodifique uma vez, grave no disco.base64.b64decode entrega bytes brutos que você pode salvar, enviar ou passar ao Pillow.
Hospede o arquivo você mesmo. Se um blog ou app precisa de um link público, envie os bytes para o seu próprio armazenamento (S3, R2, um CDN) e guarde essa URL.
Dispense o disco para prévias rápidas. Monte um data URI com f"data:image/png;base64,{b64}" e coloque-o em uma tag <img>.
💡 Migrando código antigo? Procurar .url e response_format no seu projeto encontra quase todas as linhas que precisam mudar.
Tamanho, qualidade e formato de saída
Esses parâmetros definem o que você recebe de volta e quanto custa. Esta é a lista completa que a documentação publica:
Parâmetro
Valores aceitos
Observações
size
1024x1024, 1536x1024, 1024x1536, ou WIDTHxHEIGHT personalizado
As bordas personalizadas devem ser múltiplos de 16, a proporção deve ficar entre 1:3 e 3:1, a maior borda vai até 3840 px e o total de pixels vai de 655.360 a 8.294.400
quality
low, medium, high, auto
Os modelos 2.5 também listam xhigh e max
output_format
png (padrão), jpeg, webp
Escolha webp ou jpeg para arquivos mais leves
output_compression
0 a 100
Somente JPEG e WebP
background
transparent, opaque, auto
A transparência exige um formato com canal alfa, então use PNG ou WebP
n
Inteiro
Várias imagens em uma única requisição
moderation
auto (padrão), low
low aplica uma filtragem mais leve
stream, partial_images
Booleano, de 0 a 3
Quadros de prévia enquanto a imagem final é renderizada
Algumas regras práticas:
Paisagem e retrato.1536x1024 e 1024x1536 servem para a maioria dos formatos de blog e redes sociais. Para 16:9 real, peça 2048x1152: as duas bordas são múltiplos de 16 e a contagem de pixels fica bem dentro do intervalo permitido.
Itere barato, finalize caprichado. Rascunhe os prompts em quality="low" e depois rode o vencedor de novo em high. Você paga pelos tokens de saída, e a qualidade mais alta produz mais deles.
Escolha o formato pelo destino. Mantenha o PNG para edição e transparência, e troque para webp com output_compression=85 em páginas que precisam carregar rápido.
Edite imagens existentes com máscaras
Edite uma imagem
images.edit recebe um arquivo de origem mais um prompt que descreve a mudança. Passe uma lista de arquivos quando quiser combinar várias referências.
with open("living-room.png", "rb") as photo:
edited = client.images.edit(
model="gpt-image-2.5-sunburst",
image=photo,
prompt="Swap the grey sofa for a green velvet armchair, keep the window light unchanged",
)
Path("living-room-edit.png").write_bytes(base64.b64decode(edited.data[0].b64_json))
Descreva o que deve permanecer igual com a mesma clareza com que descreve o que deve mudar. Os modelos se desviam quando o prompt só nomeia o elemento novo.
Adicione uma máscara
Uma máscara limita a edição a uma região. Ela é um PNG com canal alfa, com as mesmas dimensões da origem. Pixels totalmente transparentes marcam a área a ser repintada; tudo o que é opaco fica protegido. O Pillow monta uma em poucas linhas:
from PIL import Image, ImageDraw
base = Image.open("living-room.png").convert("RGBA")
mask = Image.new("RGBA", base.size, (0, 0, 0, 255)) # opaque: keep
ImageDraw.Draw(mask).rectangle((620, 380, 1180, 900), fill=(0, 0, 0, 0)) # transparent: repaint
mask.save("mask.png")
with open("living-room.png", "rb") as photo, open("mask.png", "rb") as hole:
edited = client.images.edit(
model="gpt-image-2.5-sunburst",
image=photo,
mask=hole,
prompt="A green velvet armchair with a wooden side table, matching the room's light",
)
A máscara é uma orientação, não um corte rígido. As bordas podem vazar um pouco, então deixe uma pequena margem em volta do objeto que você quer substituir.
Prévias em streaming e lotes
Imagens parciais enquanto você espera
Renderizações de alta qualidade podem levar um tempo. Com stream=True e partial_images, a API envia quadros de rascunho antes da imagem final, para que uma interface mostre o progresso em vez de um spinner.
stream = client.images.generate(
model="gpt-image-2.5-flare",
prompt="A vintage red bicycle leaning on a brick wall, golden hour, 35mm photograph",
size="1536x1024",
quality="high",
stream=True,
partial_images=2,
)
for event in stream:
if event.type == "image_generation.partial_image":
Path(f"preview-{event.partial_image_index}.png").write_bytes(base64.b64decode(event.b64_json))
else:
Path("final.png").write_bytes(base64.b64decode(event.b64_json))
As prévias podem aumentar a contagem de tokens, então compare usage com e sem streaming antes de ativá-lo em todas as requisições.
Lotes assíncronos sem erros de limite
Para uma lista de prompts, AsyncOpenAI junto com um semáforo mantém sob controle o número de requisições em andamento:
import asyncio
from openai import AsyncOpenAI
client = AsyncOpenAI(max_retries=4, timeout=180)
gate = asyncio.Semaphore(3)
async def render(index: int, prompt: str) -> Path:
async with gate:
result = await client.images.generate(
model="gpt-image-2.5-flare", prompt=prompt, size="1536x1024", quality="low",
)
path = Path(f"batch-{index:02d}.png")
path.write_bytes(base64.b64decode(result.data[0].b64_json))
return path
async def main(prompts: list[str]) -> list[Path]:
return await asyncio.gather(*(render(i, p) for i, p in enumerate(prompts)))
Um semáforo limita a concorrência, não as imagens por minuto. Nas faixas de uso baixas, o limite por minuto é o primeiro a dar problemas, então aumente max_retries e deixe o SDK recuar. Quando ninguém está esperando pelo resultado, o endpoint de Batch é suportado por esses modelos e cobra os tokens de saída pela metade do preço.
Custos, limites e erros
Taxas de tokens por modelo
A OpenAI precifica esses modelos por tokens, não por imagem, e não publica uma tabela por imagem para os atuais. Taxas por 1M de tokens:
Modelo
Entrada de texto
Entrada de imagem
Saída de imagem
Saída de imagem (Batch)
gpt-image-2.5-flare
$5,00
$8,00
$30,00
$15,00
gpt-image-2.5-sunburst
$5,00
$8,00
$30,00
$15,00
gpt-image-2
$5,00
$8,00
$30,00
$15,00
gpt-image-1
$5,00
$10,00
$40,00
$20,00
gpt-image-1-mini
$2,00
$2,50
$8,00
$4,00
Qualidade e tamanho mudam quantos tokens de saída uma imagem usa, e é por isso que um mesmo prompt pode custar valores bem diferentes em low e em high.
Acompanhe os gastos no código
A resposta inclui um objeto usage com a contagem de tokens. Converta isso em dólares após cada chamada e você nunca será pego de surpresa por uma fatura:
Antes de gastar orçamento de API com experimentos de prompt, rode-os no navegador. O GPT Image 2 no PicassoIA renderiza texto legível dentro das imagens, aceita fundos transparentes, recebe imagens de referência e gera até 10 variações por execução.
Teste prompts sem código
Abra a página do modelo e escreva seu prompt. Coloque entre aspas qualquer texto que deva aparecer dentro da imagem.
Defina a qualidade como low para rascunhos. Troque para high na renderização final.
Escolha uma proporção: 3:2 ou 2:3 espelham 1536x1024 e 1024x1536, e 16:9 dá um quadro panorâmico.
Escolha o formato de saída. O WebP é o padrão, o PNG mantém a transparência limpa.
Defina o número de imagens entre 1 e 10 e gere.
Envie imagens de referência se quiser editar em vez de criar do zero.
Os campos do formulário correspondem à chamada em Python, então uma receita que funciona no navegador passa direto para o código:
Campo do PicassoIA
Argumento em Python
aspect_ratio
size
quality
quality
output_format
output_format
output_compression
output_compression
background
background
moderation
moderation
number_of_images
n
input_images
image (em images.edit)
Um campo opcional aceita sua própria credencial da OpenAI; deixe-o vazio e o proxy do PicassoIA cuida da requisição.
Mais dois hábitos compensam. Primeiro, rascunhe o prompt com um modelo de linguagem: cole uma ideia bruta no GPT 5 ou no Claude Sonnet 4.6 e peça três variantes fotográficas com lente, luz e enquadramento. Segundo, rode o mesmo prompt pelo PicassoIA Image e pelo Seedream 4.5 para ver qual estilo combina com o seu projeto. Para edições que não exigem código, o PicassoIA Image Editor Pro faz alterações em fotos diretamente no navegador.
A API para desenvolvedores do PicassoIA
Se o seu pipeline precisa de outro provedor, o PicassoIA tem a própria API para desenvolvedores, com formato parecido com o da Replicate:
URL base:https://api.picassoia.com/v1
Autenticação: um token Bearer que começa com pia_sk_
Fluxo: crie uma previsão com POST /v1/models/{owner}/{name}/predictions, consulte GET /v1/predictions/{id} e depois leia o resultado
Limite: 5 predições simultâneas por conta
Os trabalhos são assíncronos, então o ciclo de criar e consultar substitui a chamada única e bloqueante que você escreveu acima. Verifique os requisitos do plano na página da API do PicassoIA antes de construir sobre ela.
Crie suas próprias imagens hoje
Agora você tem um pipeline funcionando: instale o SDK, verifique a organização, peça uma imagem, decodifique o base64, ajuste size e quality, edite com uma máscara, transmita prévias, faça lotes com limites e registre os gastos. A forma mais rápida de melhorar os resultados é o volume. Escreva dez prompts, rode-os em low, guarde os dois melhores e renderize esses de novo em high.
Se você quer testar prompts antes de mexer na API, abra o GPT Image 2 no PicassoIA, gere algumas variações e compare com outros modelos na biblioteca de modelos do PicassoIA. Quando tiver imagens fixas de que goste, a coleção de efeitos do PicassoIA pode adicionar movimento e estilo sobre elas. Escolha um assunto que importe para você, escreva um prompt detalhado e veja o que volta.