Capítulo 13 de 22 · intermedio
Generación de imágenes
Qué cubre esta sesión
La semana pasada el modelo leía imágenes. Esta semana las hace. Le mandas un prompt de texto a un modelo de imagen y recibes pixeles de vuelta — un PNG que puedes guardar, renderizar o entregarle a un usuario. La API es casi trivial; lo interesante es que el prompting de imagen es una habilidad de verdad, y es la misma habilidad que el prompting de texto orientada a un lienzo. Vago entra, genérico sale. Sé específico sobre sujeto, estilo, iluminación y composición, y obtienes algo que de verdad publicarías.
La mecánica toma cinco minutos: una llamada, prompt entra, bytes salen, decodifica y escribe. El resto de la hora es sobre las dos cosas que separan un juguete de una herramienta — plantillar un estilo de la casa para que los resultados sean consistentes, y elegir la relación de aspecto a propósito, porque la misma idea compuesta cuadrada versus ancha son en realidad dos imágenes distintas.
OpenAI
images.generate regresa datos PNG en base64. Decodifícalos, escribe los bytes,
listo. El parámetro size fija la relación de aspecto.
# One call, prompt in, image out. gpt-image-1 returns base64 PNG data; decode it
# and write the bytes. `size` controls the aspect ratio (square here; use a wide
# size for banners, a tall one for posters).
def generate(prompt: str, path: str) -> str:
response = client.images.generate(model=_MODEL, prompt=prompt, size="1024x1024")
image_bytes = base64.b64decode(response.data[0].b64_json)
with open(path, "wb") as f:
f.write(image_bytes)
return path
Nota que aquí no hay conversación — la generación de imágenes es una sola petición, no un chat, así que no hay historial que manejar. Sobre lo que iteras es el prompt. Agrega "soft watercolor," "dramatic rim lighting," "isometric," "shot on 35mm film," y observa cómo se mueve la salida; el vocabulario de la dirección de arte es el vocabulario que funciona. Conserva los prompts que aciertan — un buen prompt de imagen es reutilizable de una forma en que una buena imagen no lo es.
Gemini
El modelo de imágenes de Google a través de la llamada normal generate_content
— response_modalities pide una imagen, que regresa como un data part inline (el
endpoint aparte de Imagen quedó deprecado). La misma historia: prompt entra, bytes
salen, y el prompt es donde vive el oficio.
# Ask generate_content for an IMAGE modality; the returned parts include an
# inline_data part carrying the raw image bytes, ready to write.
def generate(prompt: str, path: str) -> str:
response = client.models.generate_content(
model=_MODEL,
contents=prompt,
config=types.GenerateContentConfig(response_modalities=["TEXT", "IMAGE"]),
)
for part in response.candidates[0].content.parts:
if getattr(part, "inline_data", None) and part.inline_data.data:
with open(path, "wb") as f:
f.write(part.inline_data.data)
return path
raise RuntimeError("no image part in response")
Dos cosas que tener en mente antes de poner esto frente a usuarios. Las imágenes generadas pueden traer watermarks del proveedor y venir con términos de uso — léelos antes de montar un negocio sobre la salida. Y la generación de imágenes es más lenta y más cara que una llamada de texto por un amplio margen; es una acción deliberada que un usuario dispara, no algo que haces en cada carga de página. Presupuéstala en consecuencia.
Ponlo a trabajar
Tres apps de docker-compose bajo code/showcase/<slug>/. Cada una regresa la
imagen como un data URI y la página la renderiza inline, así que son
appecitas genuinas, no solo texto. Mismo procedimiento:
bash bootstrap-secrets.sh, docker compose up --build,
http://localhost:3000.
Showcase 1 — Texto a imagen
La capacidad cruda: una caja de prompt, una imagen generada. Úsala para sentir cuánto importa la redacción — corre el mismo sujeto con tres cláusulas de estilo distintas y compara.
Showcase 2 — Fábrica de stickers
El usuario da un sujeto; la app lo envuelve en un estilo fijo de sticker troquelado. Este es el movimiento de productización — plantillar el prompt para que un no experto obtenga salida on-brand cada vez sin conocer el conjuro. La mayoría de las features reales de imagen son esto: un estilo fijo, un sujeto variable.
Showcase 3 — Fábrica de banners
Un banner ancho con espacio negativo para un titular. Existe para volver concreto un solo punto: la relación de aspecto es una decisión creativa de primera clase, no un pensamiento tardío. La receta del banner compone para un titular; la cuadrada no lo haría.
Las tres son la misma llamada generate con una plantilla de prompt y un size distintos. La ingeniería es el plantillado y la plomería; el producto es la receta.
Córrelo
El README de esta carpeta tiene la versión de Python, la línea de instalación,
las dos variables de entorno y los comandos exactos. Las keys vienen del .env
sin trackear en la raíz del curso. Los scripts básicos escriben un PNG que
abres; los showcases renderizan inline.
Lo que te llevas
La generación de imágenes es una llamada de un solo tiro — prompt entra, pixeles salen, sin conversación que manejar — lo que significa que toda la habilidad vive en el prompt y los parámetros. Dos movimientos convierten la capacidad cruda en una feature: plantillar un estilo de la casa para que el sujeto sea la única variable que el usuario aporta, y tratar la relación de aspecto como una decisión creativa que rehace la composición. Cuida también lo práctico — es lenta, es comparativamente cara, y la salida puede traer watermarks y términos — así que hazla una acción deliberada del usuario, nunca una automática. La próxima semana la última modalidad: audio, en ambas direcciones — de voz a texto y de regreso.