ImageScript

1.3.1 · active · verified Sun Apr 19

ImageScript is a zero-dependency JavaScript library designed for high-performance bitmap image manipulation. It supports a wide array of image formats, including decoding PNG, JPEG, TIFF, and GIF, along with capabilities for rendering SVGs and vector fonts. The library also handles encoding images to PNG, JPEG, WebP, and GIF. Currently at version 1.4.0, it distinguishes itself from other JavaScript imaging tools by leveraging lower-level memory access, reduced memory copying, and utilizing WebAssembly or native binaries for superior performance and a smaller memory footprint. It offers a comprehensive set of image manipulation functions like cropping, rotation, compositing, and various color adjustments. The project maintains an active development pace with regular updates and ships with TypeScript types, enhancing developer experience.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates loading an image, performing common manipulations like resizing, tinting, compositing another image, rendering text, and finally encoding it back to a file. It also includes an example for processing GIF files by rotating each frame. Ensure you have 'assets/example.png' and optionally 'assets/watermark.png' and 'assets/example.gif' for full functionality; dummy files will be generated if not found.

import { Image, GIF } from 'imagescript';
import { readFileSync, writeFileSync } from 'fs';

async function processImage() {
  // Load an image from a buffer
  const inputBuffer = readFileSync('./assets/example.png'); // Replace with a valid path to a PNG image
  const image = await Image.decode(inputBuffer);

  // Resize and add a red tint
  image.resize(200, Image.RESIZE_AUTO);
  image.tint(255, 0, 0, 0.2); // 20% red tint

  // Composite another image (e.g., a watermark) if available
  try {
    const watermarkBuffer = readFileSync('./assets/watermark.png'); // Optional: replace with a watermark image
    const watermark = await Image.decode(watermarkBuffer);
    watermark.resize(image.width / 4, Image.RESIZE_AUTO);
    image.composite(watermark, image.width - watermark.width - 10, image.height - watermark.height - 10);
  } catch (e) {
    console.warn('Watermark image not found, skipping compositing.');
  }

  // Render text onto the image
  image.renderText(
    'Hello ImageScript!',
    'sans-serif', // Font family (must be available in the environment)
    48,
    0, 0, // position
    0xFFFFFFFF, // white color with full alpha
    0x000000FF, // black outline with full alpha
    2
  );

  // Encode the modified image to a new PNG file
  const outputBuffer = await image.encode();
  writeFileSync('./output_image.png', outputBuffer);
  console.log('Image processed and saved to output_image.png');

  // Example of GIF decoding/encoding (requires a GIF file)
  try {
    const gifBuffer = readFileSync('./assets/example.gif'); // Replace with a valid path to a GIF image
    const gif = await GIF.decode(gifBuffer);
    gif.loop = 0; // Loop indefinitely
    gif.frames.forEach(frame => {
      frame.image.rotate(10); // Rotate each frame by 10 degrees
    });
    const outputGifBuffer = await gif.encode();
    writeFileSync('./output_gif.gif', outputGifBuffer);
    console.log('GIF processed and saved to output_gif.gif');
  } catch (e) {
    console.warn('GIF example skipped: Make sure to have a ./assets/example.gif file.');
  }
}

// Create a dummy image file for the example if it doesn't exist
try {
  readFileSync('./assets/example.png');
} catch (e) {
  console.log('Creating dummy assets for quickstart...');
  const dummyImage = new Image(300, 200);
  dummyImage.fill(0x0000FFFF); // Blue background
  dummyImage.encode().then(buffer => writeFileSync('./assets/example.png', buffer));
  const dummyWatermark = new Image(100, 50);
  dummyWatermark.fill(0xFF000088); // Semi-transparent red
  dummyWatermark.encode().then(buffer => writeFileSync('./assets/watermark.png', buffer));
  console.log('Dummy images created. Re-run quickstart after this.');
  // Exit so the user can re-run with the created files
  process.exit(0);
}

processImage().catch(console.error);

view raw JSON →