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.

API de geração de imagens da OpenAI em Python: exemplo passo a passo
Cristian Da Conceicao
Fundador do Picasso IA

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.

Mãos de um desenvolvedor digitando em um notebook sobre uma mesa de carvalho à luz suave da manhã

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.

ModeloMelhor paraPreço da saída de imagem (por 1M de tokens)
gpt-image-2.5-flareGeração rápida e de alta qualidade no dia a dia$30,00
gpt-image-2.5-sunburstEdições precisas e inpainting$30,00
gpt-image-2Lançamento anterior, mesmas taxas de tokens$30,00
gpt-image-1Modelo GPT Image original$40,00
gpt-image-1-miniMenor custo$8,00

No PicassoIA você pode testar o GPT Image 2.5 Flare, o GPT Image 2.5 Sunburst, o GPT Image 2, o GPT Image 1 e o GPT Image 1 Mini lado a lado. Um padrão sensato: Flare para gerar, Sunburst quando a tarefa for uma edição.

Instale e autentique

Instale o SDK oficial:

pip install --upgrade openai pillow

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.

Desenvolvedor revisando um primeiro script em Python em um notebook ao entardecer

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.

Fotografias impressas espalhadas em leque sobre uma mesa de nogueira

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âmetroValores aceitosObservações
size1024x1024, 1536x1024, 1024x1536, ou WIDTHxHEIGHT personalizadoAs 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
qualitylow, medium, high, autoOs modelos 2.5 também listam xhigh e max
output_formatpng (padrão), jpeg, webpEscolha webp ou jpeg para arquivos mais leves
output_compression0 a 100Somente JPEG e WebP
backgroundtransparent, opaque, autoA transparência exige um formato com canal alfa, então use PNG ou WebP
nInteiroVárias imagens em uma única requisição
moderationauto (padrão), lowlow aplica uma filtragem mais leve
stream, partial_imagesBooleano, de 0 a 3Quadros 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.

Três quadros emoldurados em formatos quadrado, paisagem e retrato sobre uma parede de tijolos

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.

Mão de um retocador com uma caneta sobre uma mesa digitalizadora ao lado de um retrato impresso

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:

ModeloEntrada de textoEntrada de imagemSaída de imagemSaí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.

Notebook, calculadora e provas impressas sobre a mesa de um freelancer

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:

RATES = {"text_in": 5.00, "image_in": 8.00, "image_out": 30.00}  # USD per 1M tokens

def cost_usd(usage) -> float:
    details = usage.input_tokens_details
    return (
        details.text_tokens * RATES["text_in"]
        + details.image_tokens * RATES["image_in"]
        + usage.output_tokens * RATES["image_out"]
    ) / 1_000_000

print(f"Last image: ${cost_usd(result.usage):.4f}")

Os limites de taxa dependem da sua faixa de uso. Para gpt-image-2.5-flare, a página do modelo lista estes limites no momento em que escrevemos:

FaixaTokens por minutoImagens por minuto
Faixa 1100 mil5
Faixa 2250 mil20
Faixa 3800 mil50
Faixa 43 milhões150
Faixa 58 milhões250

Erros com que você vai se deparar

Desenvolvedor massageando a nuca enquanto lê um erro no notebook à noite

SintomaCausa provávelCorreção
Erro de acesso na primeira chamadaOrganização não verificadaConclua a verificação no console de desenvolvedor
AttributeError em .urlOs modelos GPT Image devolvem somente base64Leia b64_json no lugar
Requisição inválida mencionando moderaçãoO prompt ou a imagem de entrada acionou um filtro de segurançaReescreva o prompt e evite assuntos sensíveis
Requisição inválida em sizeBorda que não é múltiplo de 16, proporção acima de 3:1 ou contagem de pixels fora do intervaloAjuste as dimensões
Limite de taxa de 429Limite da faixa atingidoReduza a concorrência, aumente max_retries ou use o Batch
TimeoutAlta qualidade pode levar muito tempoAumente timeout no cliente

Capture os três que mais importam em produção:

import openai

try:
    result = client.images.generate(model="gpt-image-2.5-flare", prompt=prompt, size="1536x1024")
except openai.BadRequestError as err:
    print("Rejected:", err.message)
except openai.RateLimitError:
    print("Image limit reached, slow down")
except openai.APIConnectionError:
    print("Network problem, retry later")

Como usar o GPT Image 2 no PicassoIA

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

  1. Abra a página do modelo e escreva seu prompt. Coloque entre aspas qualquer texto que deva aparecer dentro da imagem.
  2. Defina a qualidade como low para rascunhos. Troque para high na renderização final.
  3. Escolha uma proporção: 3:2 ou 2:3 espelham 1536x1024 e 1024x1536, e 16:9 dá um quadro panorâmico.
  4. Escolha o formato de saída. O WebP é o padrão, o PNG mantém a transparência limpa.
  5. Defina o número de imagens entre 1 e 10 e gere.
  6. 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 PicassoIAArgumento em Python
aspect_ratiosize
qualityquality
output_formatoutput_format
output_compressionoutput_compression
backgroundbackground
moderationmoderation
number_of_imagesn
input_imagesimage (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.

Designer deslizando por um retrato fotográfico em um tablet em um estúdio iluminado

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.

Profissional criativo diante de uma parede de estúdio coberta de fotografias impressas

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.

Compartilhe este artigo

Escolha seu idioma