@thi.ng/pixel-dither
TypeScript icon, indicating that this package has built-in type declarations

1.1.165 • Public • Published

@thi.ng/pixel-dither

npm version npm downloads Mastodon Follow

[!NOTE] This is one of 205 standalone projects, maintained as part of the @thi.ng/umbrella monorepo and anti-framework.

🚀 Please help me to work full-time on these projects by sponsoring me on GitHub. Thank you! ❤️

About

screenshot

Extensible image dithering w/ various algorithm presets. This is a support package for @thi.ng/pixel.

The package provides the following dithering algorithm presets (can also be very easily extended via definition of custom kernels):

  • Atkinson
  • Bayes (ordered dithering w/ customizable sizes & levels)
  • Burkes
  • Diffusion (1D row/column, 2D)
  • Floyd-Steinberg
  • Jarvis-Judice-Ninke
  • Sierra 2-row
  • Stucki
  • Threshold

Status

STABLE - used in production

Search or submit any issues for this package

Installation

yarn add @thi.ng/pixel-dither

ESM import:

import * as pd from "@thi.ng/pixel-dither";

Browser ESM import:

<script type="module" src="https://esm.run/@thi.ng/pixel-dither"></script>

JSDelivr documentation

For Node.js REPL:

const pd = await import("@thi.ng/pixel-dither");

Package sizes (brotli'd, pre-treeshake): ESM: 1.06 KB

Dependencies

Usage examples

Three projects in this repo's /examples directory are using this package:

Screenshot Description Live demo Source
Showcase of various dithering algorithms Demo Source
Image dithering and remapping using indexed palettes Demo Source
Multi-layer vectorization & dithering of bitmap images Demo Source

API

Generated API docs

import { imageFromURL, intBufferFromImage, GRAY8 } from "@thi.ng/pixel";
import { ditherWith, ATKINSON } from "@thi.ng/pixel-dither";

// create pixel buffer from HTML image element
const img = intBufferFromImage(await imageFromURL("test.jpg"));

// apply dithering to all channels in given pixel buffer
ditherWith(ATKINSON, img);

// first convert to 8-bit gray before dithering
ditherWith(ATKINSON, img.as(GRAY8));

// ...or apply dithering to select channels only
// use custom threshold & error spillage/bleed factor
ditherWith(ATKINSON, img, { channels: [1, 2, 3], threshold: 0.66, bleed: 0.75 });

Custom dither kernels

All bundled algorithm presets (apart from orderedDither()) are implemented as DitherKernel configurations for, defining how each dithered pixel's error should be diffused/distributed to neighbors. This approach makes it very easy to define custom dither configs, like so:

import { ditherWith, type DitherKernel } from "@thi.ng/pixel-dither";

const CUSTOM: DitherKernel = {
    // X offsets of neighbor pixels to update
    ox: [1],
    // Y offsets of neighbor pixels to update
    oy: [1],
    // error weights for updated pixels
    weights: [1],
    // bit shift (scale factor)
    shift: 1,
};

ditherWith(CUSTOM, img);

The above config will distribute the error to a single pixel @ offset (1,1). However the error will be bit-shifted by 1 bit to the right (aka division-by-2). In code form:

pixels[i + ox + oy * width] += (err * weight) >> shift;

Important: Ensure the offset positions only refer to still unprocessed pixels, i.e. those to the right and/or below the currently processed pixel (in following rows).

You can see the result of this kernel in the pixel-dither demo.

Authors

If this project contributes to an academic publication, please cite it as:

@misc{thing-pixel-dither,
  title = "@thi.ng/pixel-dither",
  author = "Karsten Schmidt",
  note = "https://thi.ng/pixel-dither",
  year = 2021
}

License

© 2021 - 2025 Karsten Schmidt // Apache License 2.0

Versions

Current Tags

VersionDownloads (Last 7 Days)Tag
1.1.16521latest

Version History

VersionDownloads (Last 7 Days)Published
1.1.16521
1.1.1640
1.1.1631
1.1.1620
1.1.1611
1.1.16010
1.1.1591
1.1.1582
1.1.1571
1.1.1560
1.1.1550
1.1.1544
1.1.1531
1.1.1520
1.1.1512
1.1.1501
1.1.1490
1.1.1480
1.1.1471
1.1.1461
1.1.1451
1.1.1441
1.1.1430
1.1.1420
1.1.1412
1.1.1401
1.1.1390
1.1.1381
1.1.1370
1.1.1360
1.1.1351
1.1.1340
1.1.13311
1.1.1320
1.1.1310
1.1.1301
1.1.1292
1.1.1280
1.1.1270
1.1.1260
1.1.1250
1.1.1240
1.1.1231
1.1.1221
1.1.1211
1.1.1200
1.1.1190
1.1.1180
1.1.1170
1.1.1160
1.1.1150
1.1.1140
1.1.1130
1.1.1120
1.1.1111
1.1.1100
1.1.1091
1.1.1081
1.1.1070
1.1.1060
1.1.1050
1.1.1040
1.1.1030
1.1.1020
1.1.1010
1.1.1000
1.1.981
1.1.971
1.1.960
1.1.950
1.1.941
1.1.930
1.1.921
1.1.910
1.1.900
1.1.890
1.1.880
1.1.870
1.1.864
1.1.852
1.1.830
1.1.821
1.1.810
1.1.801
1.1.790
1.1.781
1.1.770
1.1.762
1.1.750
1.1.740
1.1.731
1.1.720
1.1.710
1.1.701
1.1.690
1.1.681
1.1.671
1.1.661
1.1.651
1.1.640
1.1.630
1.1.621
1.1.600
1.1.590
1.1.581
1.1.571
1.1.561
1.1.550
1.1.541
1.1.530
1.1.520
1.1.510
1.1.500
1.1.492
1.1.480
1.1.471
1.1.461
1.1.450
1.1.440
1.1.431
1.1.420
1.1.400
1.1.391
1.1.382
1.1.370
1.1.361
1.1.350
1.1.341
1.1.330
1.1.321
1.1.310
1.1.301
1.1.290
1.1.282
1.1.271
1.1.261
1.1.250
1.1.240
1.1.231
1.1.220
1.1.210
1.1.200
1.1.190
1.1.180
1.1.170
1.1.160
1.1.150
1.1.141
1.1.131
1.1.121
1.1.110
1.1.100
1.1.90
1.1.80
1.1.71
1.1.62
1.1.50
1.1.41
1.1.31
1.1.21
1.1.10
1.1.00
1.0.100
1.0.90
1.0.80
1.0.70
1.0.50
1.0.40
1.0.20
1.0.10
0.1.01

Package Sidebar

Install

npm i @thi.ng/pixel-dither

Weekly Downloads

127

Version

1.1.165

License

Apache-2.0

Unpacked Size

32.5 kB

Total Files

28

Last publish

Collaborators

  • thi.ng