cd /news/artificial-intelligence/500-portadas-distintas-de-un-solo-mo… · home topics artificial-intelligence article
[ARTICLE · art-27389] src=dev.to ↗ pub= topic=artificial-intelligence verified=true sentiment=↑ positive

500 portadas distintas de un solo modelo de $0.04: arte de portada con IA, consistente con la marca, en un generador económico

A developer built a $0.04-per-cover image generator using Amazon Bedrock's Stable Image Core, achieving brand consistency through prompt engineering and post-processing rather than fine-tuning. The system overlays logos with Pillow after generation to avoid model-rendered text artifacts, and uses negative prompts to suppress unwanted elements. The architecture avoids GPU hosting and queues, keeping marginal costs low for low-volume editorial art.

read12 min publishedJun 15, 2026

La lección de cabecera: en un modelo económico, la calidad no la consigues escribiendo un mejor prompt único, la consigues decidiendo en qué es bueno el modelo, haciendo el resto tú mismo, y diseñando la variedad como una característica del producto en lugar de esperar que la semilla la entregue.

Admin (SPA) ──POST /blog/generate-image──▶ FastAPI (Fargate, us-east-1)
                                              │
                              boto3 bedrock-runtime (us-west-2)
                                              │
                                   Stable Image Core ──▶ PNG en base64 (2016×1152)
                                              │
                       Pillow: composición opcional del lockup de marca
                                              │
                          redimensionar → WebP (1200×630) → S3 → CloudFront

Una sola petición sincrónica. Sin cola, sin GPU, sin hospedar el modelo.

El endpoint es un orquestador delgado: construye un prompt, llama a

Bedrock, opcionalmente superpone el logo, y le entrega los bytes a la

pipeline de imágenes que ya existía (que quita los metadatos, redimensiona, y convierte a WebP).

La decisión arquitectónica más importante de todas es lo que no está aquí: sin modelo con ajuste fino, sin LoRA, sin grupo de autoescalado de GPU. La consistencia de marca se compra por completo con un envoltorio de prompt y un post-proceso. Eso mantiene el costo marginal de una portada en unos centavos y el costo operativo en cero, que es justo el punto para arte editorial de bajo volumen.

La primera versión hizo lo obvio: tomar el texto y mandarlo al

modelo.

body = {"prompt": admin_text, "mode": "text-to-image"}

El agente interno de autoría, mientras tanto, envolvía cada prompt en unestilo de la casa fijo. Así que las portadas hechas por el agente eran fieles a la marca y las tecleadas a mano eran un terreno sin reglas misma plataforma, dos identidades visuales. La solución es un envoltorio.

def _styled_cover_prompt(raw: str) -> str:
    return (
        "Wide editorial illustration for a community blog post. "
        f"Theme: {raw.strip()}. "
        "Modern flat-vector art style with subtle gradients, a warm "
        "purple and teal palette, optimistic mood. Abstract metaphor, "
        "no people in close-up, no readable text anywhere. "
        "Clean 16:9 hero composition."
    )

NEGATIVE = "text, words, watermark, logo, signature, low quality, blurry, frame, border"

El prompt negativo importa tanto como el positivo. text, words

está

haciendo trabajo de verdad: es la forma más barata de impedir que el

modelo garabatee letras falsas por todo el arte. Nos vamos a apoyar fuerte en eso en un momento.

Este es el estilo de la casa "plano". Luego quisimos un segundo pictórico, dorado y oscuro, para contenido gamificado / de torneo. Ahí fue donde el modelo económico empezó a mostrar sus limites.

Todo modelo de difusión de esta gama renderiza el texto como

pseudo glifos garabateados. El arte de referencia que perseguíamos tenía un wordmark; el nuestro salió como MYBRAND → MYBARND. Dos opciones: pelear con el modelo, o dejar de pedirle que haga tipografía.

Dejamos de pedírselo. El prompt positivo dice no readable text anywhere

, el prompt negativo prohíbe text, logo

, y el lockup de marca real y transparente, wordmark incluido, se superpone encima con Pillow después de generar.

El pegado ingenuo falla: un logo dorado sobre una pintura cargada de

dorado se desvanece. La solución es un respaldo oscuro difuminado detrás

del lockup, luego el lockup, abajo a la derecha:

def overlay_brand(image_bytes: bytes) -> bytes:
    base = Image.open(io.BytesIO(image_bytes)).convert("RGBA")
    logo = Image.open(LOGO_PATH).convert("RGBA")
    target_w = int(base.width * 0.22)
    logo = logo.resize((target_w, int(logo.height * target_w / logo.width)))
    x = base.width - logo.width - int(base.width * 0.035)
    y = base.height - logo.height - int(base.height * 0.035)
    base.alpha_composite(_soft_dark_ellipse(base.size, logo, x, y))  # respaldo de contraste
    base.alpha_composite(logo, (x, y))
    return _to_png(base.convert("RGB"))

Wordmark nítido, legible sobre cualquier arte, cero tipografía generada. Este es el principio general para modelos económicos: cualquier cosa que tenga que ser exacta al píxel, texto, logos, layout, lo haces en código determinista, no en el prompt.

Pedimos "un grifo de frente a un dragón". Core regresó una sola criatura con partes de grifo y de dragón fusionadas. Este es un modo de falla conocido de los modelos chicos: dos sujetos independientes en un mismo cuadro se mezclan.

Dos mitigaciones, las dos baratas:

Prompt negativo: fused creature, merged animals, two-headed, hybrid,

.

extra limbs, extra heads

Componer alrededor de arquetipos conocidos. Un consejo alrededor de una mesa redonda, un grupo de cuatro aventureros, figuras frente a un portal esas son composiciones que el modelo ha visto miles de veces y monta correctamente, multitud y todo. Un duelo libre de dos bestias distintas no lo es. Convertimos las cosas que queríamos retratar (comunidad, colaboración) en arquetipos que el modelo de verdad puede renderizar.

La regla general: no pelees contra los ajustes composicionales del modelo elige sujetos o temas que se adecuen a ellos.

Intentamos reproducir una referencia que fusionaba una taberna medieval acogedora con interfaces holográficas cian, cálido y frío, fantasía y tecnología, en un mismo cuadro. Catorce generaciones a través de cuatro estrategias de prompt después, el veredicto fue concluyente:

La tecnología enterrada en una descripción cálida → Core soltaba la

tecnología por completo (taberna pura).

La tecnología al frente → Core inundaba el cuadro de pantallas cian (sala de servidores pura).

Equilibrado, con cuentas explícitas ("dos o tres hologramas") → revertía a uno o al otro, dependiendo de la semilla.

Core no puede sostener dos estéticas fuertes y opuestas en tensión. Un modelo más fuerte (la referencia salió de uno) sí puede; Core no. Anotamos el hallazgo y seguimos adelante en lugar de quemar más generaciones contra un techo del modelo. El movimiento de ingeniería honesto en una gama económica es saber cuándo pegaste contra el muro y dejar de pagar por darle de topes, la alternativa (componer los hologramas nosotros mismos de manera procedural) era real pero no valía la pena para el valor.

Este era el problema de producto de verdad. Con el envoltorio "épico"

pesado puesto, prompts distintos producían imágenes casi idénticas. Dos

temas opuestos, "trabajo remoto asíncrono entre zonas horarias" y

"depurar una caída de producción a las 3am", los dos renderizaban al

mismo guerrero dorado con una espada en llamas. El andamio de estilo

(elementos de héroe en dorado bruñido, ambiente heroico ceremonial,

heráldica de gremio) era tan dominante que el modelo se aferraba a él e ignoraba el tema. La semilla aleatoria no ayudaba: el prompt restringe la salida mucho más de lo que la semilla la perturba.

Tres palancas, cada una medida contra la anterior:

4a. Encabeza con el tema; degrada el estilo a un tratamiento. Pon el sujeto primero, aplica el look como un acabado en lugar de como palabras clave que dictan el sujeto. De repente "trabajo remoto" renderizaba a un desarrollador frente a un mapamundi brillante y "depurar a las 3am" renderizaba a un ingeniero en un cuarto de control oscuro. Fidelidad al tema: arreglada. Pero cada portada seguía siendo dorado cálido sobre fondo oscuro.

4b. Rota la paleta. La paleta fija única era el mayor motor de

mismidad. Un conjunto rotatorio, teal/brasa/azul-acero/violeta/esmeralda/carmesí,

cada uno conservando el dorado como hilo conductor, rompió el monocromo.

El color y el ambiente ahora variaban por generación.

4c. Rota el escenario. Los temas de nuestro blog son casi sinónimos

(carreras, empleos, mentoría, comunidad), así que aun con la rotación de

paleta, "avanza en tu carrera" y "sube de nivel tus habilidades" todavía

se montaban igual. La solución que funcionó: meter el sujeto en un

escenario distinto y fiel a la marca cada vez, biblioteca, fragua, pico

de montaña, observatorio, mercado. Tres temas sinónimos de carrera luego

renderizaron como una biblioteca, una fragua, y un observatorio.

def _epic_cover_prompt(raw, motif="champion", composition=None, palette=None, setting=None):
    scene = MOTIFS.get(motif, "")
    if scene:                                  # un motivo ES el sujeto
        subject = f"{scene}, evoking {raw.strip()}"
    else:                                      # si no: el tema encabeza, metido en un escenario
        subject = f"{raw.strip()}, {setting or random.choice(SETTINGS)}"
    comp = composition or random.choice(COMPOSITIONS)
    pal  = palette or random.choice(PALETTES)
    return f"{subject}. {comp}. Rendered as painterly key-art, ... a rich {pal} palette ..."

La variedad es combinatoria y del lado del servidor: 10 escenarios × 7

paletas × 8 composiciones ≈ 560 encuadres distintos, elegidos al azar por

llamada, antes de que la semilla siquiera entre. La variedad dejó de ser

algo que esperábamos que el modelo proveyera y se volvió un espacio de

parámetros que poseemos.

Límite honesto: para exactamente el mismo tema, Core todavía tiende a

montar el sujeto igual, los modificadores de composición son débiles

contra una escena fuertemente implicada. La variedad de verdad viene de

temas distintos + paleta + escenario + semilla, no de volver a tirar un

mismo prompt.

Fase 6, un lente de campaña. Como la plataforma es gamificada (roles,

niveles, misiones), un encuadre de campaña tipo RPG se mapea sobre cada

tema: aprender = misiones, roles = clases, crecimiento = subir de nivel,

comunidad = el grupo. Es un tercer estilo junto a los otros (no

reemplazamos los que funcionan), reutilizando la misma maquinaria de

rotación con escenas de RPG, un tablero de misiones, un grupo de clases,

un árbol de habilidades. Mismo motor, narrativa más rica, más variedad

gratis.

A bajo volumen editorial, el modelo de API por imagen gana de manera

decisiva. Las cifras son precio de lista al momento de escribir (us-west-2)

y se van a mover, trátalas como proporciones, no como cotizaciones.

Opción Costo unitario Costo fijo Operación
Bedrock Stable Image Core ~$0.04 / imagen $0 ninguna
Bedrock Stable Image Ultra ~$0.14 / imagen $0 ninguna
SDXL autoalojado (g5.xlarge) ~$0 marginal ~$1.00 / hora-GPU siempre encendido o dolor de arranque en frío AMI, escalado, parchado
Google Imagen (Vertex) ~$0.04 / imagen $0 ninguna, pero una segunda nube
Midjourney n/a (suscripción) $10–60 / mes sin API sancionada

Un blog que genera un puñado de portadas al día cuesta centavos al mes en

Core. Para llegar al punto de equilibrio contra una sola g5.xlarge siempre

encendida (~$720/mes) tendrías que generar ~18,000 portadas al mes.

Nosotros generamos quizás 100. La cuenta del autoalojado solo se voltea a

una escala que nunca vamos a alcanzar para arte editorial, e incluso

entonces te apuntaste a AMIs, fijado de drivers, y un autoescalador. El

modelo más barato que pasa la barra de calidad, llamado por imagen, es la

respuesta correcta aquí, y reconocer eso temprano nos ahorró un flujo de

trabajo completo de operación de GPU.

La elección de gama dentro de Bedrock también importa: Ultra es ~3.5× el

precio de Core por una mejora de calidad que un logo post-superpuesto y la

rotación de paleta volvieron innecesaria para las miniaturas. Gastamos el

dinero donde aterriza el ojo humano (el sujeto y el color), no en un número

de gama.

Los modelos de imágenes de Bedrock no están en cada región, y el modelo

que quieres acota la región que llamas. Nuestro backend corre en

us-east-1; Stable Image Core se aprovisionó en us-west-2. Así que el

cliente está fijado a otra región a propósito:

client = boto3.client("bedrock-runtime", region_name="us-west-2")  # NO la región de la app

Tres consecuencias que vale la pena saber antes de armar la arquitectura

alrededor de esto:

La disponibilidad es por modelo, por región. "Bedrock está en mi región"

no es "este modelo está en mi región". Revisa el modelo, no el servicio.

Las llamadas a otra región agregan latencia y cruzan una frontera de

datos. Para arte de portada de dispara-y-olvida eso está bien; para

cualquier cosa sensible a la latencia o a la residencia no lo está, y

puede que necesites aprovisionar el modelo en la región de tu app o elegir

otro.

El acceso al modelo es una concesión explícita. Habilitar un modelo de

Bedrock es un paso de consola por cuenta/región, y el IAM tiene que

permitir bedrock:InvokeModel

sobre ese ARN del modelo. Un ARN con

comodín sobre el modelo base nos ahorró re-editar la política en cada

cambio de modelo.

Tipografía. Nunca. Superpón el texto y los logos tú mismo.

Dos estéticas opuestas en un cuadro (cálido/frío, fantasía/tecnología). Se

colapsa a una. Elige un carril o superpón.

Escenas libres de varios sujetos. Dos sujetos distintos se fusionan. Usa

arquetipos que el modelo ya monta (mesas, grupos, portales).

Variedad composicional por tema bajo demanda. Una escena fuertemente

implicada se monta igual sin importar las pistas de cámara. Diseña la

variedad a través de paleta/escenario/semilla en lugar de esperarla de un

solo prompt.

Ninguno de estos fue un motivo de descarte. Cada uno se volvió una

restricción de diseño que empujó el trabajo fuera del modelo y hacia

código que controlamos, que es justo donde quieres que vivan las partes

deterministas de una marca de todos modos.

Decide el trabajo del modelo, luego recupera el resto. El texto, los

logos, el layout, y la variedad exacta de marca son deterministas; hazlos

en código. Deja que el modelo pinte.

Un estilo de la casa es un envoltorio de prompt + un prompt negativo, no

un ajuste fino. Para bajo volumen, ese es todo el presupuesto de

consistencia de marca que necesitas.

La variedad es un espacio de parámetros que posees, no una semilla a la

que le cruzas los dedos. Rota los ejes que no definen la marca (paleta,

escenario, cámara); fija el que sí (aquí, el dorado).

Pon precio a la API por imagen contra una GPU con honestidad. Por debajo

de decenas de miles de imágenes al mes, la API gana en costo y en

operación, no construyas la flota.

Revisa modelo-por-región antes de armar la arquitectura. El modelo acota

la región, y la concesión es explícita.

Conoce el techo y detente ahí. Catorce generaciones nos dijeron que Core

no puede fusionar cálido y frío. Anotar eso y seguir adelante fue más

barato que un prompt ingenioso que nunca iba a llegar.

Si te llevas una sola cosa: en un modelo de imágenes económico, la calidad

y la variedad no son cosas que pides en un prompt, son cosas que diseñas

alrededor de los límites conocidos del modelo. El prompt es la parte más

chica.

── more in #artificial-intelligence 4 stories · sorted by recency
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/500-portadas-distint…] indexed:0 read:12min 2026-06-15 ·