Pro API: gerar e retocar imagens

Uma imagem custa 1 crédito, independentemente do modo. A geração a partir de um prompt e o retoque de uma imagem que forneças passam ambos pela mesma rota.

POST /images/quote aceita o mesmo corpo e responde com o preço sem criar nada, sempre { "cost": 1, ... } aqui. Existe por simetria com os vídeos, onde o preço varia.

Submeter uma imagem

POST /images

json
{ "prompt": "portrait of a woman in a rainy street at night, neon reflections, cinematic",
  "width": 832, "height": 1216 }
CampoTipoPadrãoO que faz
promptstringobrigatórioA cena. Inglês dá os resultados mais precisos.
width, heightint1024 x 1024Tamanho em píxeis. Formatos recomendados: 1024 x 1024 (quadrado), 832 x 1216 (retrato), 1216 x 832 (paisagem).
modestringgenerationedit, img2img ou inpaint, ver abaixo. Ausente significa gerar a partir do prompt.
image_b64stringImagem de origem em base64 (PNG ou JPEG), obrigatória pelos três modos de retoque. No máximo 12 MB descodificados.
mask_b64stringMáscara em base64: obrigatória para inpaint, opcional para edit. Pinta as áreas a retocar a vermelho, com o tamanho da imagem de origem.
lorastringUma personagem treinada na conta: o name devolvido por GET /loras. Coloca o seu trigger no prompt.
lora2, lora2_strengthstring, numberUma segunda personagem e a sua intensidade (0 a 1, padrão 1) para uma cena com duas pessoas.
countint1Quantas imagens gerar com este pedido, de 1 a 8. Cada uma recebe a sua própria seed; com seed, usam seed, seed+1, seed+2... É o seletor Imagens por geração da aplicação.
seedintaleatóriaSeed do render, de 0 a 4294967295. Mesma seed, mesmo prompt e mesmas definições: o mesmo render, com diferenças muito ligeiras se a placa gráfica mudar. Manter a seed e ajustar o prompt dá uma variação que preserva a composição.
stepsintmotorDeixa vazio. O motor conhece o seu próprio valor.

A resposta:

json
{ "jobId": "test-79634842-4586-46d4-ad52-d9ea236ae00d", "seed": 178078967, "cost": 1 }

A seed é devolvida na resposta, quer a tenhas indicado quer tenha sido sorteada aleatoriamente: guarda-a para renderizar a mesma imagem de novo, ou uma variação dela.

Pedir várias de uma vez

Com count acima de 1, um pedido inicia vários renders, cada um com a sua própria seed, e a resposta lista-os todos:

json
{ "count": 4, "requested": 4, "cost_total": 4,
  "jobs": [ { "jobId": "...", "seed": 178078967, "cost": 1 }, { "jobId": "...", "seed": 903412, "cost": 1 } ],
  "errors": [],
  "jobId": "...", "seed": 178078967, "cost": 1 }

Dois pontos a ler com atenção.

O jobId, a seed e o cost do primeiro render são repetidos ao nível superior. Isso existe para que clientes escritos antes dos lotes continuem a funcionar sem alterações, não porque o primeiro seja mais importante. Faz polling de todas as entradas de jobs, não apenas dessa.

E compara count com requested. Uma recusa a meio do processo, por falta de créditos ou porque a chave atingiu o limite diário, interrompe o lote onde estiver: requested é o que pediste, count é o que realmente começou, e errors explica por que parou. Um cliente que assume que os dois são iguais perde renders silenciosamente.

POST /images/quote também aceita count e calcula o preço de todo o lote. Os vídeos não têm count: um pedido, um clip.

Os três modos de retoque

Os três funcionam com o mesmo motor de edição por instrução, que preserva o aspeto da imagem de origem. Quando forneces uma imagem de origem, width e height são lidos a partir da própria imagem e não precisam de ser enviados.

modeEntradasO que o motor faz
editimage_b64 + prompt (+ mask_b64 opcional)Aplica a instrução a toda a imagem ("add sunglasses", "make it snow"). Com máscara, a alteração concentra-se dentro da área vermelha.
inpaintimage_b64 + mask_b64 + promptRegenera apenas a área vermelha da máscara, seguindo a instrução. O resto é recomposto pixel a pixel.
img2imgimage_b64 + promptRework completo da imagem seguindo o prompt, mantendo a sua composição e aspeto: uma variação.

Em edit, o servidor escolhe sozinho a melhor forma de tratar o retoque, como a app:

  • com máscara: lê a instrução e escolhe entre substituir o conteúdo da zona (outro objeto, outra peça de roupa, um rosto: a zona é redesenhada a partir do que deve lá aparecer) e modificar o que lá está (cor, material, luz). Com um lora de personagem, a zona é sempre redesenhada, rosto incluído;
  • sem máscara, com um lora de personagem ("replace the woman with kara..."): o servidor encontra a pessoa da fotografia e redesenha-a com a personagem; se não encontrar ninguém, a instrução aplica-se à imagem inteira, como antes.

Mesmo preço em todos os casos (1 crédito por imagem). A escolha vê-se no resultado, não na resposta.

bash
IMG=$(base64 -w0 photo.png)
curl -s $B/images -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d "{\"mode\":\"edit\",\"prompt\":\"add a red scarf, keep everything else identical\",\"image_b64\":\"$IMG\"}"

Criar uma imagem com personagens, objetos e um cenário

Adiciona um objeto multiref ao POST /images e o servidor põe as tuas personagens (Personagens), os teus objetos e animais e um cenário (Sujeitos) a atuar juntos numa só imagem, cada um reconhecível, como o ecrã «Criar uma imagem» da aplicação. Chama cada um por @Name no prompt, em inglês.

json
{ "prompt": "@Mia hands a cup of coffee to @Tom on a sunny terrace, both smiling",
  "multiref": {
    "characters": [
      { "character_id": "chr_8f3a...", "name": "Mia", "view": 1 },
      { "character_id": "chr_21bc...", "name": "Tom", "lora": "tom_v1", "strength": 1.0, "lora_pass": 0.55 }
    ],
    "subjects": [ { "subject_id": "sub_...", "name": "Mug" } ],
    "location": { "subject_id": "sub_...", "name": "Terrace" }
  },
  "width": 1344, "height": 768, "seed": 42, "count": 1 }
Campo de multirefO que faz
characters[].character_id, nameUma personagem de GET /characters; name é a palavra escrita após @ (letras, dígitos, _).
characters[].viewA vista da sua sheet que a representa, de 1 a 5 (1, o busto de frente, por padrão).
characters[].sheet_idOpcional: a sheet a usar (a mais recente por padrão).
characters[].loraOpcional: o seu LoRA de imagem, um nome da lista image de GET /loras. A personagem é então interpretada pelo seu LoRA, não pela sua vista.
characters[].strengthIntensidade do LoRA, de 0 a 1,5 (1 por padrão).
characters[].lora_passParte da imagem repintada pela sua passagem de LoRA, de 0,3 a 0,9 (0,55 por padrão); útil com vários sujeitos.
characters[].descriptionOpcional, em inglês: roupa, idade...
subjects[]Objetos e animais de /subjects: subject_id, name (por padrão, a primeira palavra do seu nome), description, image (qual das suas imagens, 1 por padrão).
locationUm cenário de /subjects (subject_id, name), ou um cenário pontual: background_b64 e background_description.
count1 ou 2: as imagens são renderizadas uma após a outra.
  • No máximo 4 sujeitos (personagens, objetos e animais). Sem LoRA, apenas a partir de imagens: no máximo 4 referências, cenário incluído. O servidor escolhe o método a partir das referências e coloca cada uma pela ordem de characters e depois de subjects, da esquerda para a direita.
  • Um @Name que não corresponde a nenhuma referência é recusado (unknown_mention); uma referência ausente do prompt é enviada na mesma.
  • Preço: uma passagem custa o preço de uma imagem (1 crédito). Uma imagem simples é 1 passagem; várias personagens interpretadas por um LoRA, 1 mais uma passagem por LoRA (no máximo 4); apenas a partir de imagens, uma passagem por referência além da primeira; uma mistura, ambos. O total (passagens x count) é reservado na submissão e debitado uma única vez, na imagem final: uma falha ou um cancelamento não custa nada. POST /images/quote com o mesmo corpo dá o preço exato, o método e as suas passagens, sem iniciar nada.
  • Resposta 202: { "jobId": "mri_...", "seed", "cost", "method", "passes", "billed_passes" } (com count 2: jobs e cost_total). O polling, o download e o cancelamento usam as rotas habituais abaixo; durante a renderização, progress indica a passagem em curso ("2/3"). Uma imagem demora 1 a 3 minutos.
  • A imagem final fica disponível durante 1 hora, e 10 minutos após o seu primeiro download. Uma passagem falhada dá status: "failed" com reason: "render_failed"; um cancelamento, reason: "cancelled".
  • Erros: invalid_count, invalid_view, invalid_lora_pass, invalid_subject_image, invalid_size, character_not_ready, mais os do Multi-Ref (unknown_character, unknown_subject, unknown_lora, unknown_mention, multiref_too_many_references, invalid_strength...). Ver Limites e erros.

Polling

GET /images/{jobId}

RespostaSignificado
{ "status": "pending", "phase": "IN_QUEUE" }Em fila
{ "status": "pending", "phase": "IN_PROGRESS" }A renderizar
{ "status": "completed", "cost": 1, "file_url": "/pro/v1/images/{jobId}/file", ... }Concluído, ficheiro pronto
{ "status": "failed", "detail": "..." }Falhou, e nada é cobrado

Faz polling a cada 3 segundos, não mais rápido: a fila é partilhada.

Download

GET /images/{jobId}/file

O próprio PNG, como corpo da resposta (Content-Type: image/png). Disponível assim que o estado for completed, e 404 media_unavailable assim que o render for eliminado. Faz o download imediatamente, pois não fica arquivado.

Cancelar

POST /images/{jobId}/cancel

Cancela um render em fila ou em execução. Responde { "ok": true }. Nada é cobrado, e o custo reservado contra o limite diário da chave é devolvido.

Windows · Mac · Cloud ou local

Gera em privado. Esta noite.

Descarrega a tendre.AI gratuitamente e gera sem limites, de forma privada, na tua própria GPU.

OS Windows 10/11GPU NVIDIA 8GB+VRAM 12GB recomendadoDisco 20GB

Mac: Apple silicon (M1 ou posterior), macOS 13 ou posterior. Os Macs Intel não são suportados.

A geração local de imagens no Mac precisa de um M4 com 24 GB de memória, ou um M2 ou M3 Pro, Max ou Ultra com 24 GB. Abaixo disso, tudo corre online com créditos. Por agora, a retoque e o vídeo correm online no Mac.

Tudo sobre o tendre.AI para Mac

Sem GPU NVIDIA? Começa 100% na cloud: 5 imagens grátis e 1 vídeo grátis todos os dias. Uma placa NVIDIA (8GB+) desbloqueia a geração local ilimitada.