Credenciales IA (Rebrandeable)
Fecha de creación del post: 18 de Noviembre de 2025
Autor: Abraham García
Wiki Técnica – Arquitectura, Flujo, Prompting y Rebranding
Introducción
Este proyecto fue creado originalmente para Walmart, pero fue diseñado desde cero para ser totalmente rebrandeable, escalable y fácil de adaptar a cualquier marca o empresa.
Su función principal es permitir al usuario:
- Tomarse una fotografía con su cámara.
- Enviarla a un backend que ejecuta un proceso de transformación mediante IA.
- Recibir una versión estilizada (Disney/Pixar style) incrustada en una credencial o tarjeta de identificación.
- Descargar la credencial final directamente desde el navegador.
La esencia del proyecto es la composición inteligente entre:
- Prompt (texto)
- Imagen del usuario
- Template (background/base)
El template jamás se modifica desde IA; la IA solo genera al sujeto transformado.
Tecnologías Utilizadas
Front-End
- React.js
- react-router-dom
- Context API
- html2canvas
Back-End
- Node.js
- Express
- Sharp (post-procesamiento)
- SDK oficial de Gemini Banana / Gemini Flash
Infraestructura
- DigitalOcean Spaces (S3 compatible)
- Render (hosting del backend usado en el ejemplo)
Arquitectura General
[ Usuario ] ↓ (captura foto) [ React Front ] —— FormData → [ Node Backend ] ↓ IA Gemini (Prompt) ↓ Postprocesado con Sharp ↓ Carga en DigitalOcean ↓ (url) [ React Front – credencial ] ↓ html2canvas → Descarga PNG
Flujo en el Front-End
Formulario Inicial
La aplicación comienza con un formulario simple que recopila:
- Nombre del usuario
- Datos generales
- Acciones iniciales
Aquí solo interviene React y el router.
**Componente **Photo.jsx**
Este componente:
- Habilita la cámara
- Muestra una previsualización en un
<video> - Copia un frame al
<canvas>oculto - Convierte ese canvas en un blob
Creación de canvas y captura
<canvas ref={canvasRef} style={{ display: "none" }} />
<Button
onClick={() => {
canvasRef.current.toBlob(async (blob) => {
updateImg(blob);
stopCamera();
navigate("/result");
});
}}
className={"w-[384px]"}
> Generar foto
> </Button>
Función de captura
El botón usa toBlob() para extraer la imagen exacta del usuario.
Esto permite:
- Mostrar la foto original en el resultado final (para previsualización).
- Enviar la foto al backend junto con el nombre del usuario.
Componente Result.jsx: Envío de la Foto
La fotografía se envía mediante FormData, junto con el nombre.
const uploadImg = useCallback(async () => {
if (refPhoto.current) return;
refPhoto.current = true;
const formData = new FormData();
formData.append("file", img, `${name}.png`);
formData.append("name", name);
setIsLoading(true);
try {
const res = await axios.post(
"https://walmart-activacion-back-node.onrender.com/api/images/create",
formData
);
const { payload } = res.data;
const { url } = payload;
setResult(url);
} finally {
setIsLoading(false);
refPhoto.current = false;
}
}, [img, name]);
Flujo en el Back-End
Al backend llegan:
- file → imagen del usuario
- name → nombre del usuario
const { file } = req.files;
const { name } = req.body;
Proceso en el Backend
- Generar imagen AI mediante Gemini.
- Postprocesar la imagen con Sharp (dimensiones y limpieza).
- Subir la imagen final a DigitalOcean (bucket S3).
- Retornar la URL pública.
Generación de Imagen con Gemini
Se utiliza:
- modelo: gemini-2.5-flash-image-preview
- aspectRatio: "3:4"
Además, se envía un arreglo content que combina:
- Texto (prompt)
- Foto del usuario
- Template (sin modificaciones)
Sobre el Prompt
El prompt debe estar diseñado con:
- XML correcto
- Markdown correcto
- Especificidad absoluta
- Indicaciones descriptivas, técnicas y visuales
Prompt engineering → [ Documentación ]
Ejemplo de Prompt Utilizado
`
## ROLE & MISSION
You are an expert **AI digital artist and compositor**. Transform the person from **image[1]** into a **3D Disney/Pixar–style cartoon** and composite them onto the **unaltered background template** **image[0]**. **All rules below are absolute.**
---
## ABSOLUTE CRITICAL RULES (PRIORITY ORDER)
1) **VERTICAL CANVAS EXACTNESS**
- Final output **must be portrait/vertical** with **exact dimensions: 832 × 1252 px (2:3)**.
- Do **not** swap width/height, rotate, auto-orient from EXIF, or return landscape. Any non-832×1252 result is **invalid**.
2) **TEMPLATE IMMUTABILITY**
- **image[0]** is **immutable** and must remain **pixel-for-pixel, bit-for-bit identical** in the final image. Just the template follows this rule.
- Do **not** crop, resize, resample, rotate, recolor, filter, blur, add noise, mask, paint, or alter **any** template pixel.
- All four template edges must remain fully visible.
3) **MANDATORY STYLIZATION (SUBJECT)**
- The person from **image[1]** **must** be rendered as a **3D Disney/Pixar-style cartoon**. The subject can and must be transformd, the template can't.
- Returning the original (photographic) subject is **invalid**.
- **Never** photorealistic, semi-realistic, or 2D/anime.
- The person must be located upper the space white. Not over, it must be in a higher position
4) **CLEAN COMPOSITION (NO EXTRA ELEMENTS)**
- The **only** new pixels allowed over the template are:
**(a)** the stylized subject and **(b)** a subtle silhouette **contour shadow (2–8 px, soft/diffused)** hugging the subject.
- No frames, borders, stickers, props, external text, watermarks, logos, gradients, scenes, or textures.
> **Conflict resolution:** 1 Vertical 832x1252 → 2 Template immutability → 3 Mandatory stylization → 4 Clean composition.
---
## CHARACTER STYLIZATION & DETAILS (from image[1])
- **Identity preservation:** keep skin tone, eye color, facial proportions (nose, jawline), hair color/style; the result must be clearly recognizable.
- **Clothing & accessories:** replicate exactly what is present in **image[1]**.
- **Do not** add, remove, or invent garments, logos, or accessories.
- If the person does **not** wear glasses or accessories, **do not** add any.
- **Framing & pose:** chest-up portrait; three-quarter turn facing the **viewer’s right**; gaze to the viewer’s right.
- **Edge integration:** clean edges; avoid halos or a “sticker” look.
- **Contour shadow:** soft, diffused, **2–8 px**; must not spill onto or contaminate template elements.
---
## COMPOSITION & POSITIONING
- **Subject placement zone:** keep the stylized character **strictly within the upper 75%** of the canvas.
- **Exclusion zone:** the **bottom 25%** of the canvas must remain **empty**, showing only the pristine, untouched template (image[0]); no subject or shadow may enter this zone.
---
## FIXED OUTPUT DIMENSIONS (RESTATE)
- **Canvas:** exactly **832 × 1252 px**, **2:3 vertical**.
- **No** cropping, padding, or rescaling of the **final canvas** is permitted.
---
## FINAL OUTPUT CHECKLIST (QUALITY GATES)
- [ ] **Canvas** is **exactly 832 × 1252 px (2:3 vertical)**; not rotated or landscape.
- [ ] **Background** is an **identical, unaltered copy** of **image[0]**, all edges visible.
- [ ] **Subject** is **3D Disney/Pixar-style**, **never** photorealistic/semi-realistic/2D.
- [ ] **Clothing & accessories** match the source exactly; none invented (no glasses if none in source).
- [ ] **Composition:** subject entirely in the **upper 75%**; **bottom 25%** is clean template only.
- [ ] **Contour shadow** present (2–8 px), soft and natural; no spill or contamination.
- [ ] **No extra elements** (frames, text, logos, gradients, scenes, textures, props).
---
`
Consideraciones Críticas
Limitación del modelo
La función generateContent genera imágenes cuadradas.
Por lo tanto:
- Si necesitas dimensiones exactas (832×1252, 600×900, etc.)
- Debes aplicar postprocesado obligatorio con Sharp
Postprocesamiento con Sharp
Actualmente se hace:
- Limpieza del fondo blanco
- Redimensionado
- Centrado
- Preparación a 300 DPI
const DPI = 300;
const W = 2 _ DPI; // 600
const H = 3 _ DPI; // 900
Almacenamiento en DigitalOcean
- Se sube la imagen final al bucket S3.
- Se obtiene una URL pública.
- El front utiliza esta URL para colocar un footer (nombre + logo).
Rebranding del Proyecto
El proyecto es completamente rebrandeable modificando solo:
Front-End
- Logos del formulario
- Logo del inicio
- Footer que se coloca sobre la credencial
- Paleta de colores
Back-End
- Template que se envía a la IA
- Prompt (si cambia el estilo o estética deseada)
Si deseas otra transformación (anime, comic, pixel art, futurista, etc.):
- Solo necesitas cambiar el prompt
- Pero debes ser extremadamente específico para obtener calidad constante
Descarga de Imágenes (Front-End)
Se usa html2canvas para convertir el contenedor HTML en PNG descargable.
const handleDownload = async () => {
const element = document.getElementById(url);
const canvas = await html2canvas(element, { useCORS: true });
const dataUrl = canvas.toDataURL("image/png");
const link = document.createElement("a");
link.download = `${Date.now()}_${name}`;
link.href = dataUrl;
link.click();
};