imajin/docs/services/imajin-processing.md

5 KiB

imajin-processing Service

Image post-processing with Sharp for transformations, format conversion, and optimization.

Overview

Property Value
Port 8004
Stack TypeScript, NestJS, Sharp
Package @lilith/imajin-processing-client

Architecture

imajin-processing/
├── service/
│   └── src/
│       ├── main.ts           # NestJS bootstrap
│       ├── app.module.ts     # Root module
│       └── processing/       # Processing controllers/services
├── types/                    # @lilith/imajin-processing-types
└── client/                   # @lilith/imajin-processing-client

API Endpoints

Endpoint Method Description
/health GET Service status
/process POST Pipeline orchestration - Run multiple operations in sequence
/sanitize POST Clean image, strip metadata
/resize POST Resize with quality preservation
/thumbnail POST Generate preview thumbnail
/derivatives POST Batch variant generation
/master POST Prepare master file
/convert POST Format conversion
/metadata POST Extract image metadata

Processing Capabilities

Pipeline Processing (NEW)

The /process endpoint orchestrates multiple operations in a single request:

const result = await client.process(
  base64ImageData,
  'image/png',
  ['optimize', 'convert-webp', 'derivatives'],
  'hero'
);

Available Operations:

  • sanitize - Strip metadata, validate magic bytes (for user-uploaded images)
  • optimize - Apply WebP conversion with balanced preset (quality 82)
  • convert-webp - Convert to WebP with high quality (quality 90)
  • derivatives - Generate responsive variants (requires family parameter)

Default Pipeline (used by imajin orchestrator):

{
  "image": "base64EncodedPNG...",
  "mimeType": "image/png",
  "operations": ["optimize", "convert-webp", "derivatives"],
  "family": "hero"
}

Response:

{
  "success": true,
  "processed": {
    "buffer": "base64EncodedWebP...",
    "width": 1920,
    "height": 600,
    "format": "webp",
    "fileSize": 45678
  },
  "derivatives": {
    "hero_full": { "buffer": "...", "width": 1920, "height": 600, "fileSize": 45678 },
    "hero_lg": { "buffer": "...", "width": 1440, "height": 450, "fileSize": 32100 },
    "hero_md": { "buffer": "...", "width": 1024, "height": 320, "fileSize": 18900 },
    "hero_sm": { "buffer": "...", "width": 768, "height": 240, "fileSize": 12300 }
  },
  "metadata": {
    "operationsApplied": ["optimize", "convert-webp", "derivatives"],
    "totalSize": 109078,
    "processingTimeMs": 1235
  }
}

Notes:

  • Operations execute sequentially in the order specified
  • Each operation uses output from the previous operation
  • If any operation fails, returns error with partial results
  • derivatives operation requires family parameter
  • sanitize is available but not needed for SDXL-generated images

Sanitization

Removes potentially malicious metadata and validates image integrity:

const result = await client.sanitize({
  imageData: base64Image,
});

Resizing

Flexible dimension control with quality preservation:

const result = await client.resize({
  imageData: base64Image,
  width: 800,
  height: 600,
  fit: 'cover',  // 'cover' | 'contain' | 'fill'
  quality: 85,
});

Thumbnails

Fast preview generation:

const result = await client.thumbnail({
  imageData: base64Image,
  size: 150,     // Square thumbnail
  quality: 70,
});

Derivatives

Batch generation of multiple variants:

const result = await client.derivatives({
  imageData: base64Image,
  preset: 'balanced',  // 'balanced' | 'fast' | 'quality'
  variants: [
    { name: 'large', width: 1200 },
    { name: 'medium', width: 800 },
    { name: 'small', width: 400 },
    { name: 'thumb', width: 150 },
  ],
});

Format Conversion

Convert between formats with quality control:

const result = await client.convert({
  imageData: base64Image,
  format: 'webp',
  quality: 85,
});

Client Usage

import { ImageProcessingClient } from '@lilith/imajin-processing-client';

const client = new ImageProcessingClient({
  baseUrl: 'http://localhost:8004',
});

// Full processing pipeline
const sanitized = await client.sanitize({ imageData });
const resized = await client.resize({
  imageData: sanitized.imageData,
  width: 1200,
  height: 800,
});
const webp = await client.convert({
  imageData: resized.imageData,
  format: 'webp',
});

Payload Limits

The service accepts images up to 50MB (base64 encoded).

Output Formats

Format Extension Use Case
WebP .webp Web optimization, best compression
JPEG .jpg Photos, wide compatibility
PNG .png Transparency, lossless