Providing descriptive alt text for images is crucial for accessibility and SEO. However, manually writing alt text for numerous images can be tedious and error-prone. Thankfully, AWS Rekognition combined with Node.js offers a powerful solution to automate this process.

Why automate alt text?

Alt text helps visually impaired users understand image content through screen readers and significantly boosts your site's SEO by providing context to search engines. Automating this process ensures consistency, saves time, and enhances user experience.

AWS Rekognition and Node.js integration

AWS Rekognition is a powerful image analysis service capable of detecting objects, scenes, and activities within images. Integrating it with Node.js allows developers to quickly build scalable applications that automatically generate descriptive alt text.

Setting up your environment

First, ensure you have:

  • An AWS account with Rekognition enabled
  • Node.js installed (v16 or later recommended)
  • AWS SDK v3 for JavaScript

Install the AWS SDK:

npm install @aws-sdk/client-rekognition dotenv

Create a .env file to securely store your AWS credentials:

AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_REGION=your-region

Image requirements

Before implementing the solution, be aware of AWS Rekognition's image requirements:

  • Supported formats: JPEG and PNG
  • Maximum image size: 5MB for direct bytes upload
  • Maximum image dimensions: 1920x1080 pixels

Exceeding these limits may result in errors or reduced accuracy.

Implementing the alt text generator

Here's a practical Node.js script to generate alt text using AWS Rekognition:

import { RekognitionClient, DetectLabelsCommand } from '@aws-sdk/client-rekognition'
import fs from 'fs'
import dotenv from 'dotenv'

dotenv.config()

const client = new RekognitionClient({ region: process.env.AWS_REGION })

async function generateAltText(imagePath) {
  const imageBytes = fs.readFileSync(imagePath)

  const command = new DetectLabelsCommand({
    Image: { Bytes: imageBytes },
    MaxLabels: 5,
    MinConfidence: 75,
  })

  try {
    const response = await client.send(command)
    const labels = response.Labels.map((label) => label.Name).join(', ')
    return `Image contains: ${labels}`
  } catch (error) {
    console.error('Error generating alt text:', error)
    return 'Image description unavailable'
  }
}

// Example usage
generateAltText('./example.jpg').then(console.log)

Save this code with a .mjs extension to use ES modules, or modify it to use CommonJS syntax with .js extension.

Processing images from S3

In production environments, you'll often need to process images stored in Amazon S3. Here's how to modify the code to work with S3:

import { RekognitionClient, DetectLabelsCommand } from '@aws-sdk/client-rekognition'
import dotenv from 'dotenv'

dotenv.config()

const client = new RekognitionClient({ region: process.env.AWS_REGION })

async function generateAltTextFromS3(bucket, key) {
  const command = new DetectLabelsCommand({
    Image: {
      S3Object: {
        Bucket: bucket,
        Name: key,
      },
    },
    MaxLabels: 5,
    MinConfidence: 75,
  })

  try {
    const response = await client.send(command)
    const labels = response.Labels.map((label) => label.Name).join(', ')
    return `Image contains: ${labels}`
  } catch (error) {
    console.error('Error generating alt text:', error)
    return 'Image description unavailable'
  }
}

// Example usage
generateAltTextFromS3('my-bucket', 'images/example.jpg').then(console.log)

Handling edge cases and errors

Robust error handling is crucial for production applications. Here's an improved error handling implementation:

try {
  const response = await client.send(command)
  const labels = response.Labels.map((label) => label.Name).join(', ')
  return `Image contains: ${labels}`
} catch (error) {
  if (error.name === 'InvalidImageFormatException') {
    console.error('Invalid image format. Only JPEG and PNG are supported.')
    return 'Image format not supported'
  } else if (error.name === 'InvalidParameterException') {
    console.error('Invalid parameters provided to AWS Rekognition')
    return 'Unable to process image'
  } else if (error.name === 'ImageTooLargeException') {
    console.error('Image size exceeds the 5MB limit')
    return 'Image too large to process'
  } else if (error.name === 'AccessDeniedException') {
    console.error('AWS credentials lack permission to use Rekognition')
    return 'Service access error'
  } else if (error.name === 'ThrottlingException') {
    console.error('AWS request rate exceeded limits')
    return 'Service temporarily unavailable'
  }
  console.error('Unexpected error:', error)
  return 'Image description unavailable'
}

Enhancing functionality

To further enhance your alt text generator:

Implement caching

Store generated alt texts in a database or cache to avoid redundant API calls:

import { createClient } from 'redis'

const redisClient = createClient()
await redisClient.connect()

async function getCachedOrGenerateAltText(imagePath) {
  const imageHash = createHash(imagePath) // Implement a hashing function

  // Try to get from cache first
  const cachedAltText = await redisClient.get(`alt_text:${imageHash}`)
  if (cachedAltText) return cachedAltText

  // Generate new alt text
  const altText = await generateAltText(imagePath)

  // Cache the result (expire after 30 days)
  await redisClient.set(`alt_text:${imageHash}`, altText, { EX: 60 * 60 * 24 * 30 })

  return altText
}

Batch processing

Process multiple images simultaneously for efficiency:

async function batchProcessImages(imagePaths) {
  return Promise.all(imagePaths.map((path) => generateAltText(path)))
}

// Example usage
const results = await batchProcessImages(['image1.jpg', 'image2.jpg', 'image3.jpg'])

Confidence threshold tuning

Adjust the confidence threshold based on your needs:

async function generateAltText(imagePath, minConfidence = 75) {
  // ... existing code
  const command = new DetectLabelsCommand({
    Image: { Bytes: imageBytes },
    MaxLabels: 5,
    MinConfidence: minConfidence, // Adjustable confidence threshold
  })
  // ... rest of function
}

Closing thoughts

Automating alt text generation with AWS Rekognition and Node.js significantly improves accessibility and SEO, streamlining your workflow and ensuring consistency across your projects. The solution is scalable, customizable, and can be integrated into various web applications and content management systems.

If you're looking for a managed solution, consider exploring Transloadit's 🤖 Artificial Intelligence Service, which simplifies image analysis and alt text generation even further.