Extraer texto de imágenes con Node.js y AWS Rekognition
Usa la operación DetectText de AWS Rekognition para leer texto en letreros,
etiquetas y otras imágenes desde Node.js. Esta guía crea una CLI que acepta un JPEG o PNG local,
o un objeto existente de S3, e imprime las líneas detectadas con puntuaciones de confianza y
geometría.
Introducción a AWS Rekognition y la detección de texto
DetectText devuelve detecciones tanto de LINE como de
WORD. Imprimir ambas repite el mismo texto, por lo que nuestra CLI devuelve
solo las líneas y las cuenta. Una línea detectada puede ser parte de una oración; el resultado
no representa la estructura de párrafos de un documento ni garantiza un orden de lectura. AWS
documenta un máximo de 100 palabras detectadas por imagen en su
guía de detección de texto.
Para el OCR de formularios, tablas y documentos de varias páginas, evalúa
Amazon Textract como alternativa.
Configuración de AWS Rekognition
Necesitas una cuenta de AWS y un perfil local autenticado o un rol de IAM que permita
rekognition:DetectText. Esta acción usa Resource: "*"; no opera sobre una
colección de Rekognition. Un administrador puede conceder acceso con la siguiente política:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "rekognition:DetectText",
"Resource": "*"
}
]
}
Usa el método de autenticación existente de tu organización. Para un perfil local, completa la
configuración de autenticación del AWS SDK
e inicia sesión antes de ejecutar el ejemplo. Dejamos credentials sin definir
para que la cadena predeterminada de proveedores de credenciales
pueda resolver tu perfil o rol. También se admiten credenciales de entorno; las credenciales
temporales necesitan AWS_SESSION_TOKEN, además de la clave de acceso y la clave secreta.
Mantén los valores de las credenciales fuera de los archivos de código fuente y de la salida de
la terminal.
Elige una región de AWS compatible.
Los comandos siguientes usan us-east-1; reemplázalo por tu región y
MY_PROFILE por el nombre de tu perfil. Para un rol de IAM en un entorno
desplegado, omite AWS_PROFILE. Enviar una imagen a Rekognition envía su contenido
a AWS y puede generar un cargo.
Instalación del AWS SDK para Node.js
Instala Node.js 24 LTS con npm. El ejemplo se probó con
Node.js 24.21.0 y la versión 3.1148.0 de @aws-sdk/client-rekognition del AWS SDK v3. La versión
de parche de Node.js es una versión probada, no un requisito intrínseco de la API; las versiones
posteriores de la misma versión principal que sigan recibiendo mantenimiento son adecuadas.
Los comandos de shell usan Bash y se probaron en Linux. Usa un shell sin
NODE_OPTIONS para que los cargadores inyectados no alteren la resolución de
módulos del nuevo proyecto.
Ejecuta esto desde un directorio donde quieras crear un nuevo proyecto
rekognition-text. El subshell mantiene tu directorio actual sin cambios, y
mkdir rechaza un proyecto existente. La instalación apunta explícitamente
al nuevo proyecto, incluso dentro de otro proyecto de npm o Yarn:
(
command -v node >/dev/null || { printf 'Install Node.js first.\n' >&2; exit 1; }
command -v npm >/dev/null || { printf 'Install npm first.\n' >&2; exit 1; }
[ -z "${NODE_OPTIONS:-}" ] || { printf 'Use a shell without NODE_OPTIONS.\n' >&2; exit 1; }
mkdir rekognition-text && cd rekognition-text &&
printf '{"private":true,"type":"module"}\n' > package.json &&
npm install --prefix "$PWD" --workspaces=false --ignore-scripts --save-exact \
@aws-sdk/client-rekognition@3.1148.0
)
Si la instalación falla después de la creación, conserva el directorio y vuelve a ejecutar el
comando npm install desde su interior. No repitas mkdir
ni sobrescribas un proyecto que ya contenga tu trabajo. Conserva el
package-lock.json resultante al compartir el ejemplo.
Integración del AWS SDK en una aplicación Node.js
Crea rekognition-text/detect-text.mjs con este primer bloque. La extensión
.mjs hace explícito su formato de módulo, incluso dentro de un proyecto
CommonJS. maxAttempts: 1 hace que cada invocación intente realizar un análisis
sin reintentos automáticos:
import { DetectTextCommand, RekognitionClient } from '@aws-sdk/client-rekognition'
const client = new RekognitionClient({
region: process.env.AWS_REGION,
maxAttempts: 1,
})
Detección de texto con AWS Rekognition
Añade el siguiente bloque al mismo archivo. La ruta local se abre directamente, sin interpretar
secuencias de escape de URL ni depender de su extensión. Su lectura se limita a 5 MiB más un byte
para rechazar los archivos demasiado grandes antes de un análisis. Usa un archivo regular que
no cambie mientras se lee. El SDK acepta Buffer directamente y
gestiona la codificación en base64.
AWS valida el formato de la imagen y decodifica su contenido; una respuesta exitosa no demuestra
que una imagen dañada se haya recuperado por completo.
import { open } from 'node:fs/promises'
class InputError extends Error {}
async function localBytes(path) {
const file = await open(path, 'r')
try {
const info = await file.stat()
const limit = 5 * 1024 * 1024
if (!info.isFile() || info.size === 0 || info.size > limit) {
throw new InputError('Use a nonempty regular image file of at most 5 MiB.')
}
const buffer = Buffer.alloc(limit + 1)
let length = 0
while (length < buffer.length) {
const { bytesRead } = await file.read(buffer, length, buffer.length - length, null)
if (bytesRead === 0) break
length += bytesRead
}
if (length === 0 || length > limit) {
throw new InputError('Use a nonempty image file of at most 5 MiB.')
}
return buffer.subarray(0, length)
} finally {
await file.close()
}
}
async function main() {
const [mode, first, second, ...extra] = process.argv.slice(2)
if (!process.env.AWS_REGION) throw new InputError('Set AWS_REGION before running the CLI.')
let image
let source
if (mode === 'local' && first && second === undefined && extra.length === 0) {
image = { Bytes: await localBytes(first) }
source = { mode, path: first }
} else if (mode === 's3' && first && second && extra.length === 0) {
image = { S3Object: { Bucket: first, Name: second } }
source = { mode, bucket: first, key: second }
} else {
throw new InputError('Usage: node detect-text.mjs local PATH | s3 BUCKET KEY')
}
const response = await client.send(new DetectTextCommand({ Image: image }))
const lines = (response.TextDetections ?? [])
.filter((item) => item.Type === 'LINE')
.map((item) => ({
text: item.DetectedText,
confidence: item.Confidence,
boundingBox: item.Geometry?.BoundingBox,
polygon: item.Geometry?.Polygon,
}))
console.log(JSON.stringify({ source, lineCount: lines.length, lines }, null, 2))
}
main()
.catch((error) => {
const codes = [
'AccessDeniedException', 'CredentialsProviderError', 'InvalidImageFormatException',
'ImageTooLargeException', 'InvalidParameterException', 'InvalidS3ObjectException',
'ProvisionedThroughputExceededException', 'ThrottlingException', 'ENOENT', 'EACCES',
]
const name = error instanceof Error && 'code' in error ? error.code : error?.name
const code = codes.includes(name) ? name : 'RequestError'
console.error(error instanceof InputError ? error.message : `Text detection failed (${code}).`)
process.exitCode = 1
})
.finally(() => client.destroy())
Análisis de imágenes de S3
El modo s3 envía el bucket y la clave exacta a Rekognition; no descarga
el objeto en Node.js. Usa un objeto privado existente en un bucket de S3 de propósito general en
la misma región que AWS_REGION. La identidad que realiza la llamada
necesita s3:GetObject sobre ese objeto, además de
rekognition:DetectText. No se necesita un bucket público ni un rol de servicio para esta
operación síncrona. Consulta el contrato de entrada de S3
y el procedimiento de análisis de imágenes.
Proporciona la clave sin codificar, como images/sign %20.png, en lugar de una URL de S3
o una clave codificada como URL. Este ejemplo lee el objeto actual y no especifica una versión.
Los objetos de S3 que probamos usan cifrado SSE-S3; los objetos cifrados con KMS pueden requerir
permisos adicionales sobre la clave. La CLI no crea, modifica ni elimina objetos de S3.
Ejemplo práctico y fragmentos de código
Coloca tu imagen en rekognition-text/photo.png. Desde el directorio padre, ejecuta:
(
cd rekognition-text &&
AWS_PROFILE=MY_PROFILE AWS_REGION=us-east-1 node detect-text.mjs local './photo.png'
)
Para una imagen ya subida a S3, reemplaza MY_BUCKET y
images/photo.png por tu bucket y tu clave, y usa la misma región que ese bucket:
(
cd rekognition-text &&
AWS_PROFILE=MY_PROFILE AWS_REGION=us-east-1 node detect-text.mjs s3 'MY_BUCKET' 'images/photo.png'
)
El JSON identifica el origen solicitado y contiene solo las líneas detectadas. Para una imagen
clara con una línea, comprueba que lineCount sea uno y que
lines[0].text coincida con el texto visible de la imagen.
Una puntuación de confianza
se expresa en una escala de 0–100; no es una garantía de exactitud. El
rectángulo delimitador
usa coordenadas relativas a la imagen. Para una imagen en posición vertical de 1.000 píxeles de
ancho, un valor de Left de 0.1 significa
100 píxeles desde el borde izquierdo. El polígono indica las esquinas de la región detectada.
Los campos opcionales que AWS omite también se omiten del JSON, en lugar de rellenarlos con
valores inventados.
Un análisis exitoso que no encuentra líneas imprime lineCount: 0 y un array
lines vacío y termina con código cero. Esto puede ocurrir con una imagen
en blanco o cuando no se reconoce el texto. En cambio, un archivo ausente, una entrada no válida,
un problema de credenciales o una solicitud fallida a AWS escribe un diagnóstico en stderr y
termina con un código distinto de cero; no imprime un JSON de éxito. Compara el texto con la
imagen original antes de usarlo para ingresar datos o para accesibilidad.
Límites y precios del servicio AWS Rekognition
La documentación de límites del servicio de AWS indica que admite JPEG y PNG como entrada, un mínimo de 80 píxeles para ambas dimensiones de la imagen y un máximo de 100 palabras detectadas. Indica un límite de 5 MB para los bytes sin codificar y de 15 MB para los objetos de S3. Esta CLI limita la entrada local a exactamente 5.242.880 bytes, incluidos los datos adicionales al final; la representación en base64 del SDK aumenta el consumo de memoria. Para la entrada de S3, AWS aplica su límite de objetos. Comprueba el tamaño y las dimensiones del objeto almacenado antes de realizar la llamada, en lugar de suponer que un archivo comprimido pequeño cumple todas las restricciones.
Usa la referencia de errores de la API
para resolver problemas. Para InvalidS3ObjectException, comprueba la clave exacta, la región
y los permisos de lectura del objeto. Para los errores de imagen, comprueba el formato real,
las dimensiones y el tamaño en bytes. Un fallo de acceso o de credenciales requiere corregir la
autenticación o los permisos. Los fallos de capacidad de procesamiento y de limitación de
solicitudes pueden reintentarse con una espera progresiva después de comprobar tu uso; este
ejemplo deja esa decisión en tus manos en lugar de ocultar análisis repetidos.
Consulta los precios de AWS Rekognition según tu región, API, volumen y la elegibilidad de tu cuenta. El almacenamiento y las solicitudes de S3 tienen cargos independientes.
Conclusión
Usa las líneas devueltas como posibles resultados de OCR y conserva la geometría cuando necesites localizar texto en una imagen. Si también necesitas un pipeline de procesamiento de imágenes, consulta Image Describe Robot de Transloadit para una etapa de análisis de imágenes gestionada; su API y su salida difieren de las de esta CLI.
