ClassifAI

Image Optimization

Learn how to compress and resize images to stay within request size limits

Overview

ClassifAI has request size limits based on your subscription tier:

  • Free (Test): 500 KB per request
  • Hobby: 2.5 MB per request
  • Production: 10 MB per request

When including images in your classification requests, the images are sent as base64-encoded data, which increases the size by approximately 33%. This guide shows you how to optimize images to stay within your tier's limits.

Quick Tips

  1. Resize images to smaller dimensions before encoding
  2. Compress images using lower quality settings
  3. Convert to JPEG format (more efficient than PNG for photos)
  4. Remove unnecessary metadata (EXIF data, color profiles)

Python Example

Here's how to optimize images in Python before sending to ClassifAI:

from PIL import Image
import io
import base64

def optimize_image_for_classification(image_path: str, max_size_kb: int = 400) -> str:
    """
    Optimize an image to stay within size limits.

    Args:
        image_path: Path to the image file
        max_size_kb: Maximum size in KB (default 400KB to stay under 500KB limit with JSON overhead)

    Returns:
        Base64-encoded optimized image
    """
    # Open the image
    img = Image.open(image_path)

    # Convert RGBA to RGB (remove alpha channel)
    if img.mode == 'RGBA':
        img = img.convert('RGB')

    # Start with reasonable dimensions
    max_dimension = 1024
    quality = 85

    while True:
        # Resize if too large
        if max(img.size) > max_dimension:
            img.thumbnail((max_dimension, max_dimension), Image.Resampling.LANCZOS)

        # Save to bytes with current quality
        buffer = io.BytesIO()
        img.save(buffer, format='JPEG', quality=quality, optimize=True)
        size_kb = buffer.tell() / 1024

        # Check if we're within limits
        if size_kb <= max_size_kb:
            buffer.seek(0)
            return base64.b64encode(buffer.read()).decode('utf-8')

        # Reduce quality or dimensions for next iteration
        if quality > 60:
            quality -= 10
        else:
            max_dimension = int(max_dimension * 0.8)
            img = Image.open(image_path)  # Reload to avoid cumulative resizing
            if img.mode == 'RGBA':
                img = img.convert('RGB')

        # Safety check
        if max_dimension < 256:
            raise ValueError("Cannot optimize image small enough while maintaining readability")

# Usage
image_base64 = optimize_image_for_classification("photo.jpg", max_size_kb=400)

# Send to ClassifAI
response = requests.post(
    "https://api.classifai.dev/classify",
    json={
        "content": [{"type": "image", "content": image_base64}],
        "labels": ["cat", "dog", "bird"]
    }
)

JavaScript/Node.js Example

const sharp = require('sharp');
const fs = require('fs').promises;

async function optimizeImageForClassification(imagePath, maxSizeKB = 400) {
  let quality = 85;
  let width = 1024;

  while (true) {
    // Resize and compress
    const buffer = await sharp(imagePath)
      .resize(width, width, {
        fit: 'inside',
        withoutEnlargement: true
      })
      .jpeg({ quality, mozjpeg: true })
      .toBuffer();

    const sizeKB = buffer.length / 1024;

    if (sizeKB <= maxSizeKB) {
      return buffer.toString('base64');
    }

    // Reduce quality or dimensions
    if (quality > 60) {
      quality -= 10;
    } else {
      width = Math.floor(width * 0.8);
    }

    if (width < 256) {
      throw new Error('Cannot optimize image small enough');
    }
  }
}

// Usage
const imageBase64 = await optimizeImageForClassification('photo.jpg', 400);

const response = await fetch('https://api.classifai.dev/classify', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    content: [{ type: 'image', content: imageBase64 }],
    labels: ['cat', 'dog', 'bird']
  })
});

Understanding Base64 Overhead

Base64 encoding increases file size by approximately 33%. Here's why:

  • Original binary: 8 bits per byte
  • Base64: 6 bits per character, encoded as 8-bit ASCII
  • Overhead: 8/6 ≈ 1.33x

Example:

  • 300 KB JPEG → ~400 KB base64 encoded
  • 750 KB JPEG → ~1 MB base64 encoded

Image Size Guidelines

Free Tier (500 KB limit)

  • Maximum original image: ~375 KB
  • Recommended dimensions: 1024×1024 or smaller
  • Format: JPEG at 75-85% quality

Hobby Tier (2.5 MB limit)

  • Maximum original image: ~1.9 MB
  • Recommended dimensions: 2048×2048 or smaller
  • Format: JPEG at 85-90% quality

Production Tier (10 MB limit)

  • Maximum original image: ~7.5 MB
  • Recommended dimensions: 4096×4096 or smaller
  • Format: JPEG at 90-95% quality or PNG if needed

Best Practices

  1. Process images before encoding - Don't encode first then realize it's too large
  2. Test your pipeline - Verify optimized images still classify correctly
  3. Cache optimized images - Don't re-optimize the same image multiple times
  4. Monitor request sizes - Log sizes to identify optimization opportunities
  5. Upgrade tiers - If hitting limits frequently, consider upgrading your plan

Multi-Image Requests

When sending multiple images in one request, the total request size includes all images combined:

# Example: Multiple images in one request
images = []
for path in ['img1.jpg', 'img2.jpg', 'img3.jpg']:
    # Optimize each image to ~130KB (400KB / 3 images)
    img_base64 = optimize_image_for_classification(path, max_size_kb=130)
    images.append({"type": "image", "content": img_base64})

response = requests.post(
    "https://api.classifai.dev/classify",
    json={
        "content": images,
        "labels": ["relevant", "not_relevant"]
    }
)

Troubleshooting

Error: "Request size exceeds tier limit"

This means your request is too large. Solutions:

  1. Reduce image quality
  2. Resize images to smaller dimensions
  3. Send fewer images per request
  4. Upgrade to a higher tier

Images are too compressed

If classification accuracy drops due to compression:

  1. Increase quality slightly
  2. Ensure minimum dimensions (512×512 recommended)
  3. Consider upgrading to a higher tier for less aggressive compression

Need Help?

If you're consistently hitting size limits with your use case, contact us to discuss custom solutions or enterprise plans.