X Enterprises
fastify-ximagepipeline

Image Utilities

Pure image processing functions for EXIF stripping, variant generation, blurhash creation, and metadata extraction — importable standalone from the pipeline plugin.

Image Utilities

Imported from @xenterprises/fastify-ximagepipeline/image. These functions are used internally by the plugin's background worker but are also available for standalone use — e.g. in scripts, test fixtures, or custom processing pipelines.

Usage

import {
  stripExif,
  getImageMetadata,
  compressToJpeg,
  generateVariants,
  generateBlurhash,
  calculateFitDimensions,
  getAspectRatio,
  validateImage,
  processImage,
} from '@xenterprises/fastify-ximagepipeline/image'

Functions

stripExif(buffer)

Remove EXIF metadata from an image buffer while preserving orientation.

Parameters:

NameTypeRequiredDescription
bufferBufferYesRaw image buffer.

Returns: Promise<Buffer> — A new buffer with EXIF data stripped.


getImageMetadata(buffer)

Extract intrinsic properties from an image buffer.

Parameters:

NameTypeRequiredDescription
bufferBufferYesRaw image buffer.

Returns: Promise<{ width: number; height: number; format: string; colorspace: string; hasAlpha: boolean; density: number }>


compressToJpeg(buffer, quality?)

Compress an image to JPEG format using mozjpeg encoding.

Parameters:

NameTypeRequiredDescription
bufferBufferYesSource image buffer.
qualitynumberNoJPEG quality (1–100). Default 85.

Returns: Promise<Buffer> — JPEG-encoded buffer.


generateVariants(buffer, specs, sourceType, quality?)

Generate multiple WebP variants from a single source buffer according to variant dimension specs.

Parameters:

NameTypeRequiredDescription
bufferBufferYesSource image buffer (post EXIF strip).
specsobjectYesMap of variant name to { width, height, fit } — see Default Variants.
sourceTypestringYesSource type key (e.g. "avatar", "gallery"). Controls which variant names are generated.
qualitynumberNoWebP quality (1–100). Defaults to per-source-type config.

Returns: Promise<Record<string, Buffer>> — Map of variant name to WebP buffer.


generateBlurhash(buffer)

Create a compact blurhash placeholder string from an image buffer.

Parameters:

NameTypeRequiredDescription
bufferBufferYesSource image buffer.

Returns: Promise<string> — A 4×3 component blurhash string (e.g. "LKO2?U%2Tw=w]~RBVZRi").


calculateFitDimensions(srcW, srcH, maxW, maxH)

Compute output dimensions that preserve aspect ratio within a bounding box.

Parameters:

NameTypeRequiredDescription
srcWnumberYesSource width in pixels.
srcHnumberYesSource height in pixels.
maxWnumberYesMaximum output width.
maxHnumberYesMaximum output height.

Returns: { width: number; height: number }


getAspectRatio(width, height)

Return a simplified aspect ratio string.

Parameters:

NameTypeRequiredDescription
widthnumberYesImage width in pixels.
heightnumberYesImage height in pixels.

Returns: string — e.g. "16:9", "4:3", "1:1".


validateImage(buffer, options?)

Validate that a buffer is an accepted image format and optionally enforce dimension constraints.

Parameters:

NameTypeRequiredDescription
bufferBufferYesRaw image buffer.
options.minWidthnumberNoMinimum width in pixels.
options.minHeightnumberNoMinimum height in pixels.
options.maxWidthnumberNoMaximum width in pixels.
options.maxHeightnumberNoMaximum height in pixels.
options.allowedFormatsstring[]NoAccepted Sharp format names (e.g. ["jpeg", "png", "webp"]).

Returns: Promise<{ valid: boolean; errors: string[] }>


processImage(buffer, sourceType, config)

Run the full processing pipeline on a single image: EXIF strip → metadata extraction → variant generation → blurhash.

Parameters:

NameTypeRequiredDescription
bufferBufferYesRaw source image buffer.
sourceTypestringYesSource type key controlling which variants are produced.
configobjectYesFull plugin config object (variants, quality, sourceTypes, etc.).

Returns:

Promise<{
  variants: Record<string, Buffer>
  blurhash: string
  metadata: { width: number; height: number; format: string; colorspace: string; hasAlpha: boolean; density: number }
}>

Examples

Strip EXIF and get metadata

import { stripExif, getImageMetadata } from '@xenterprises/fastify-ximagepipeline/image'

const raw = fs.readFileSync('./photo.jpg')
const clean = await stripExif(raw)
const meta = await getImageMetadata(clean)

console.log(meta.width, meta.height, meta.format)
// 3024 4032 "jpeg"

Generate a blurhash for an uploaded image

import { generateBlurhash } from '@xenterprises/fastify-ximagepipeline/image'

fastify.post('/upload-preview', async (request, reply) => {
  const data = await request.file()
  const buffer = await data.toBuffer()
  const hash = await generateBlurhash(buffer)
  return reply.send({ blurhash: hash })
})

Validate before storing

import { validateImage } from '@xenterprises/fastify-ximagepipeline/image'

const { valid, errors } = await validateImage(buffer, {
  minWidth: 200,
  minHeight: 200,
  allowedFormats: ['jpeg', 'png', 'webp'],
})

if (!valid) {
  throw new Error(`Invalid image: ${errors.join(', ')}`)
}

Run the full pipeline in a script

import { processImage } from '@xenterprises/fastify-ximagepipeline/image'

const buffer = fs.readFileSync('./hero.jpg')
const { variants, blurhash, metadata } = await processImage(buffer, 'hero', pluginConfig)

console.log(Object.keys(variants))  // ["lg", "xl", "2xl"]
console.log(blurhash)               // "LKO2?U%2Tw=w]~RBVZRi"

AI Context

import: "@xenterprises/fastify-ximagepipeline/image"
use-when: >
  When you need image processing functions (EXIF stripping, WebP variant generation,
  blurhash, metadata, validation) outside of the plugin's automatic pipeline —
  e.g. in CLI scripts, test helpers, or custom workers that don't use the Fastify decorator.
functions:
  - stripExif: Remove EXIF from a buffer
  - getImageMetadata: Get width/height/format/colorspace
  - compressToJpeg: Re-encode to JPEG with mozjpeg
  - generateVariants: Produce named WebP variants per spec map
  - generateBlurhash: 4x3 component blurhash string
  - calculateFitDimensions: Aspect-ratio-safe resize math
  - getAspectRatio: Human-readable ratio string
  - validateImage: Check format and dimension constraints
  - processImage: Full pipeline (strip → meta → variants → blurhash)
Copyright © 2026