CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-image-size

Fast, lightweight NodeJS package to get dimensions of any image file or buffer

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

file-processing.mddocs/

File Processing

Asynchronous dimension extraction directly from image files with configurable concurrency control. This approach is recommended for local file operations as it provides better performance and resource management.

Capabilities

Asynchronous File Dimension Extraction

Extracts dimensions from image files asynchronously with automatic concurrency management.

/**
 * Extract dimensions from image file asynchronously
 * @param filePath - Relative or absolute path to image file
 * @returns Promise resolving to dimension data
 * @throws Error if file doesn't exist, is empty, or unsupported format
 */
function imageSizeFromFile(filePath: string): Promise<ISizeCalculationResult>;

interface ISizeCalculationResult {
  /** Image width in pixels */
  width: number;
  /** Image height in pixels */
  height: number;
  /** JPEG EXIF orientation (1-8) if present */
  orientation?: number;
  /** Detected image format string */
  type?: string;
  /** Array of all sizes for multi-size formats (ICO, CUR, HEIF) */
  images?: ISize[];
}

Usage Examples:

import { imageSizeFromFile } from "image-size/fromFile";

// Basic file processing
const dimensions = await imageSizeFromFile("photos/vacation.jpg");
console.log(`${dimensions.width}x${dimensions.height}`); // 4032x3024
console.log(`Type: ${dimensions.type}`); // Type: jpg

// Process multiple files
const files = ["image1.png", "image2.jpg", "image3.webp"];
const results = await Promise.all(
  files.map(file => imageSizeFromFile(file))
);
results.forEach((result, index) => {
  console.log(`${files[index]}: ${result.width}x${result.height}`);
});

// Handle relative and absolute paths
const relativeResult = await imageSizeFromFile("./assets/logo.png");
const absoluteResult = await imageSizeFromFile("/home/user/pictures/photo.jpg");

// Multi-size formats
const iconInfo = await imageSizeFromFile("favicon.ico");
console.log(`Main: ${iconInfo.width}x${iconInfo.height}`); // Largest size
if (iconInfo.images) {
  console.log("Available sizes:");
  iconInfo.images.forEach(size => 
    console.log(`  ${size.width}x${size.height}`)
  );
}

// JPEG orientation handling
const photoInfo = await imageSizeFromFile("rotated-photo.jpg");
if (photoInfo.orientation) {
  console.log(`Orientation: ${photoInfo.orientation}`); // 1-8 EXIF value
}

Concurrency Control

Manage the number of concurrent file operations to prevent resource exhaustion.

/**
 * Set maximum concurrent file operations
 * @param c - Maximum number of concurrent file reads (default: 100)
 * @returns void
 */
function setConcurrency(c: number): void;

Usage Examples:

import { imageSizeFromFile, setConcurrency } from "image-size/fromFile";

// Default concurrency is 100
console.log("Using default concurrency (100)");

// Reduce concurrency for resource-constrained environments
setConcurrency(10);

// Process many files with controlled concurrency
const imageFiles = Array.from({ length: 1000 }, (_, i) => `image${i}.jpg`);
const startTime = Date.now();

const results = await Promise.all(
  imageFiles.map(file => imageSizeFromFile(file))
);

console.log(`Processed ${results.length} images in ${Date.now() - startTime}ms`);

// Increase concurrency for high-performance environments
setConcurrency(500);

// For batch processing scenarios
async function processBatch(files: string[], batchSize: number = 50) {
  setConcurrency(batchSize);
  
  const results = [];
  for (let i = 0; i < files.length; i += batchSize) {
    const batch = files.slice(i, i + batchSize);
    const batchResults = await Promise.all(
      batch.map(file => imageSizeFromFile(file))
    );
    results.push(...batchResults);
    console.log(`Processed batch ${Math.floor(i / batchSize) + 1}`);
  }
  
  return results;
}

Error Handling

File processing can encounter various error conditions:

import { imageSizeFromFile } from "image-size/fromFile";

try {
  const result = await imageSizeFromFile("nonexistent.jpg");
} catch (error) {
  console.log(error.message); // ENOENT: no such file or directory
}

try {
  const result = await imageSizeFromFile("empty-file.jpg");
} catch (error) {
  console.log(error.message); // "Empty file"
}

try {
  const result = await imageSizeFromFile("corrupted.jpg");
} catch (error) {
  console.log(error.message); // "unsupported file type: undefined"
}

// Handle errors gracefully
async function safeImageSize(filePath: string) {
  try {
    return await imageSizeFromFile(filePath);
  } catch (error) {
    console.error(`Failed to process ${filePath}:`, error.message);
    return null;
  }
}

// Batch processing with error handling
async function processImagesWithErrors(files: string[]) {
  const results = await Promise.allSettled(
    files.map(file => imageSizeFromFile(file))
  );
  
  const successful = results
    .filter(result => result.status === 'fulfilled')
    .map(result => (result as PromiseFulfilledResult<any>).value);
    
  const failed = results
    .filter(result => result.status === 'rejected')
    .map((result, index) => ({
      file: files[index],
      error: (result as PromiseRejectedResult).reason.message
    }));
    
  return { successful, failed };
}

Performance Notes

  • Memory Efficient: Reads only image headers (up to 512KB max)
  • Concurrency Control: Default limit of 100 prevents file descriptor exhaustion
  • Non-blocking: Asynchronous operations don't block the event loop
  • Queue Management: Internal queue system manages file operations efficiently
  • Resource Management: Automatically closes file handles after reading

CLI Usage

The package includes a command-line interface for quick image inspection:

# Install globally or use npx
npm install -g image-size
# or
npx image-size image1.jpg image2.png

# Example output:
# 1920x1080 - vacation.jpg (jpg)
# 256x256 - logo.png (png)
# 64x64 - favicon.ico (ico)
# 128x128 - favicon.ico (ico)

The CLI tool uses imageSizeFromFile internally and displays all available sizes for multi-size formats.

docs

buffer-processing.md

file-processing.md

index.md

tile.json