npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

openseadragon-filters

v2.2.0

Published

A plugin that provides the capability to apply filters to images in OpenSeadragon.

Readme

OpenSeadragon Filters

codecov npm version License: MIT Build Status Downloads

A high-performance OpenSeadragon plugin that provides real-time image filtering capabilities using WebGL acceleration.

🎨 Live Demo | 📦 NPM Package

Features

  • WebGL-accelerated filtering for optimal performance
  • 🎯 Multiple built-in filters: brightness, contrast, gamma, threshold, invert, greyscale
  • 🔧 Customizable: create your own filters
  • 🎭 Per-item filtering: apply different filters to different images (canvas mode)
  • 🔄 Two rendering modes: tile-based (canvas) or viewport-based (WebGL overlay)
  • 📦 TypeScript support: full type definitions included
  • 🌐 Modern ESM/CJS: supports both module formats

Requirements

  • OpenSeadragon 5.0+
  • Node.js 20+ (for development)

Installation

npm install openseadragon-filters

or

yarn add openseadragon-filters

Quick Start

Canvas-Based Filtering (Tile-by-Tile)

import OpenSeadragon from 'openseadragon';
import { initializeFiltering, BRIGHTNESS } from 'openseadragon-filters';

const viewer = OpenSeadragon({
  id: 'viewer',
  tileSources: 'path/to/image.dzi'
});

const filterPlugin = initializeFiltering(viewer);
filterPlugin.setFilterOptions({
  filters: {
    processors: BRIGHTNESS(50)
  }
});

WebGL-Based Filtering (Viewport Overlay)

import OpenSeadragon from 'openseadragon';
import { initWebGLFiltering, BRIGHTNESS_WEBGL } from 'openseadragon-filters';

const viewer = OpenSeadragon({
  id: 'viewer',
  tileSources: 'path/to/image.dzi'
});

// Initialize after viewer is ready
viewer.addOnceHandler('open', () => {
  const filterPlugin = initWebGLFiltering(viewer);
  filterPlugin.setFilters([BRIGHTNESS_WEBGL(50)]);
});

Usage

This plugin provides two filtering approaches:

1. Canvas-Based Filtering (Tile-by-Tile)

Filters each tile individually as it loads. Best for per-tile effects and compatibility.

Single Filter

import { initializeFiltering, BRIGHTNESS } from 'openseadragon-filters';

const filterPlugin = initializeFiltering(viewer);
filterPlugin.setFilterOptions({
  filters: {
    processors: BRIGHTNESS(50)
  }
});

Multiple Filters

Filters are applied in the order specified:

import { initializeFiltering, BRIGHTNESS, INVERT, CONTRAST } from 'openseadragon-filters';

filterPlugin.setFilterOptions({
  filters: {
    processors: [
      BRIGHTNESS(-50),
      CONTRAST(1.5),
      INVERT()
    ]
  }
});

Per-Item Filtering

Apply different filters to specific images:

import { initializeFiltering, BRIGHTNESS, INVERT } from 'openseadragon-filters';

filterPlugin.setFilterOptions({
  filters: [
    {
      items: viewer.world.getItemAt(0),
      processors: [BRIGHTNESS(50)]
    },
    {
      items: [viewer.world.getItemAt(1), viewer.world.getItemAt(2)],
      processors: [INVERT()]
    }
  ]
});

Note: If the items property is not specified, filters are applied to all items in the viewer.

Load Modes

The canvas-based plugin supports two rendering modes:

Async Mode (Default)

Tiles are progressively filtered as they load, preventing browser freezing:

filterPlugin.setFilterOptions({
  filters: { processors: BRIGHTNESS(50) },
  loadMode: 'async' // default
});
Sync Mode

Filters are applied immediately for faster rendering with simple filters:

filterPlugin.setFilterOptions({
  filters: { processors: BRIGHTNESS(50) },
  loadMode: 'sync'
});

Tip: Use sync mode for fast, synchronous filters. Use async mode for complex or slow filters to maintain UI responsiveness.

2. WebGL-Based Filtering (Viewport Overlay)

Applies filters to the entire viewport using WebGL. Best for real-time performance and viewport-level effects.

Important: Initialize WebGL filtering after the viewer is ready using the open event.

Basic Usage

import { initWebGLFiltering, BRIGHTNESS_WEBGL, CONTRAST_WEBGL } from 'openseadragon-filters';

viewer.addOnceHandler('open', () => {
  const filterPlugin = initWebGLFiltering(viewer);

  // Single filter
  filterPlugin.setFilters([BRIGHTNESS_WEBGL(50)]);

  // Multiple filters
  filterPlugin.setFilters([
    BRIGHTNESS_WEBGL(50),
    CONTRAST_WEBGL(1.5)
  ]);

  // Clear filters
  filterPlugin.clearFilters();
});

Custom WebGL Filters

import { convertToWebGLFilter } from 'openseadragon-filters';

const customShader = `
precision mediump float;
uniform sampler2D u_image;
uniform float u_intensity;
varying vec2 v_texCoord;
void main() {
  vec4 color = texture2D(u_image, v_texCoord);
  gl_FragColor = vec4(color.rgb * u_intensity, color.a);
}
`;

viewer.addOnceHandler('open', () => {
  const filterPlugin = initWebGLFiltering(viewer);
  const customFilter = convertToWebGLFilter('custom', customShader, { u_intensity: 1.5 });
  filterPlugin.setFilters([customFilter]);
});

Choosing Between Canvas and WebGL

| Feature | Canvas-Based | WebGL-Based | |---------|-------------|-------------| | Performance | Good for simple filters | Excellent for all filters | | Per-tile filtering | ✅ Yes | ❌ No (viewport only) | | Per-item filtering | ✅ Yes | ❌ No | | Custom filters | Canvas API | GLSL shaders | | Browser support | Universal | Requires WebGL | | Best for | Tile-specific effects, compatibility | Real-time performance, viewport effects |

Built-in Filters

Canvas Filters

Use with initializeFiltering():

BRIGHTNESS(adjustment)

Adjusts pixel intensity.

  • Range: -255 to 255
  • Effect: Negative values darken, positive values brighten
BRIGHTNESS(50)  // Increase brightness
BRIGHTNESS(-50) // Decrease brightness

CONTRAST(adjustment)

Adjusts image contrast.

  • Range: 0 to ∞ (typically 0-3)
  • Effect: Values < 1 reduce contrast, values > 1 increase contrast
CONTRAST(1.5) // Increase contrast
CONTRAST(0.5) // Decrease contrast

GAMMA(adjustment)

Applies gamma correction.

  • Range: 0 to 5
  • Effect: Values < 1 darken, values > 1 brighten
GAMMA(2.2) // Standard gamma correction
GAMMA(0.5) // Darken image

THRESHOLDING(threshold)

Converts image to black and white based on threshold.

  • Range: 0 to 255
  • Effect: Pixels ≥ threshold become white, others become black
THRESHOLDING(128) // Standard threshold

GREYSCALE()

Converts image to greyscale.

GREYSCALE()

INVERT()

Inverts all colors.

INVERT()

WebGL Filters

Use with initWebGLFiltering(). Same parameters as canvas filters but with _WEBGL suffix:

import { 
  BRIGHTNESS_WEBGL, 
  CONTRAST_WEBGL, 
  GAMMA_WEBGL,
  THRESHOLDING_WEBGL,
  GREYSCALE_WEBGL,
  INVERT_WEBGL
} from 'openseadragon-filters';

// Usage
filterPlugin.setFilters([
  BRIGHTNESS_WEBGL(50),
  CONTRAST_WEBGL(1.5),
  GAMMA_WEBGL(2.2)
]);

Custom Filters

Canvas Custom Filters

Create custom filters by implementing a function that processes canvas context:

function customFilter(context, callback) {
  const imageData = context.getImageData(0, 0, context.canvas.width, context.canvas.height);
  const pixels = imageData.data;
  
  // Modify pixels (RGBA format)
  for (let i = 0; i < pixels.length; i += 4) {
    pixels[i] = 255 - pixels[i];     // Red
    pixels[i + 1] = 255 - pixels[i + 1]; // Green
    pixels[i + 2] = 255 - pixels[i + 2]; // Blue
    // pixels[i + 3] is alpha
  }
  
  context.putImageData(imageData, 0, 0);
  callback();
}

// Use the custom filter
filterPlugin.setFilterOptions({
  filters: {
    processors: customFilter
  }
});

Custom Filter Requirements

  1. Accept a CanvasRenderingContext2D as the first parameter
  2. Accept a callback function as the second parameter
  3. Call the callback when processing is complete
  4. Use context.getImageData() to read pixels
  5. Use context.putImageData() to write modified pixels

API Reference

Canvas-Based API

initializeFiltering(viewer)

Initializes the filtering plugin for an OpenSeadragon viewer.

Parameters:

  • viewer (OpenSeadragon.Viewer): The OpenSeadragon viewer instance

Returns: FilterPlugin instance

filterPlugin.setFilterOptions(options)

Configures and applies filters.

Parameters:

  • options.filters (Object|Array): Filter configuration
    • processors (Function|Array): Single filter or array of filters
    • items (TiledImage|Array): Optional. Specific items to filter
  • options.loadMode (String): Optional. 'async' (default) or 'sync'

WebGL-Based API

initWebGLFiltering(viewer)

Initializes WebGL viewport filtering for an OpenSeadragon viewer.

Parameters:

  • viewer (OpenSeadragon.Viewer): The OpenSeadragon viewer instance

Returns: Object with methods:

  • setFilters(filters): Apply WebGL filters
  • clearFilters(): Remove all filters
  • destroy(): Clean up resources

filterPlugin.setFilters(filters)

Applies WebGL filters to the viewport.

Parameters:

  • filters (Array): Array of WebGLFilterConfig objects

Example:

filterPlugin.setFilters([
  BRIGHTNESS_WEBGL(50),
  CONTRAST_WEBGL(1.5)
]);

convertToWebGLFilter(name, shader, uniforms)

Creates a custom WebGL filter configuration.

Parameters:

  • name (String): Filter identifier
  • shader (String): GLSL fragment shader source
  • uniforms (Object): Shader uniform values

Returns: WebGLFilterConfig object

TypeScript Support

Full TypeScript definitions are included:

import OpenSeadragon from 'openseadragon';
import { 
  initializeFiltering, 
  initWebGLFiltering,
  BRIGHTNESS, 
  BRIGHTNESS_WEBGL,
  FilterPlugin 
} from 'openseadragon-filters';

// Canvas-based
const viewer: OpenSeadragon.Viewer = OpenSeadragon({ id: 'viewer' });
const filterPlugin: FilterPlugin = initializeFiltering(viewer);
filterPlugin.setFilterOptions({
  filters: {
    processors: BRIGHTNESS(50)
  }
});

// WebGL-based
viewer.addOnceHandler('open', () => {
  const webglPlugin = initWebGLFiltering(viewer);
  webglPlugin.setFilters([BRIGHTNESS_WEBGL(50)]);
});

Known Limitations

Tile Edge Effects

The canvas-based plugin processes tiles independently and does not handle cross-tile boundaries. Kernel-based filters may produce visible artifacts at tile edges.

Development

Setup

git clone https://github.com/rssaini01/openseadragon-filters.git
cd openseadragon-filters
npm install

Build

npm run build        # Build library
npm run dev          # Start demo dev server
npm run build:demo   # Build demo site

Testing

npm test             # Run tests
npm run test:watch   # Run tests in watch mode

Project Structure

openseadragon-filters/
├── src/                 # Source code
│   ├── index.ts        # Main entry point
│   ├── predefined-filters.ts
│   └── webgl-*.ts      # WebGL implementation
├── site/               # Demo application
├── tests/              # Test suite
└── dist/               # Built output
    ├── esm/           # ES modules
    ├── cjs/           # CommonJS
    └── types/         # TypeScript definitions

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Please ensure:

  • Tests pass (npm test)
  • Code follows existing style
  • TypeScript types are updated

License

MIT © Ravi Shankar Saini

See LICENSE for details.

Acknowledgments

  • Built for OpenSeadragon
  • Inspired by image processing needs in digital libraries and archives

Links