Porter-Duff operators for packed ints & float-array alpha compositing
npm install @thi.ng/porter-duff
!npm downloads

> [!NOTE]
> This is one of 214 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
- References
- Status
- Related packages
- Installation
- Dependencies
- Usage examples
- API
- Basic usage
- Operators
- Custom operators
- Additional operators / modifiers
- Pre/post-multiplied colors
- Authors
- License
Porter-Duff operators for packed ints & float-array alpha compositing.
This package provides all 13 fundamental
Porter-Duff
compositing / blending operators, and utilities to pre/post-multiply
alpha. All operators are available for packed ARGB/ABGR 32bit packed
ints or RGBA float vectors.
- https://keithp.com/~keithp/porterduff/p253-porter.pdf (original paper)
- https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
- https://ciechanow.ski/alpha-compositing/
- http://www.adriancourreges.com/blog/2017/05/09/beware-of-transparent-pixels/
- http://ssp.impulsetrain.com/porterduff.html
STABLE - used in production
Search or submit any issues for this package
- @thi.ng/pixel - Typedarray integer & float pixel buffers w/ customizable formats, blitting, drawing, convolution
- @thi.ng/shader-ast-stdlib - Function collection for modular GPGPU / shader programming with @thi.ng/shader-ast
``bash`
yarn add @thi.ng/porter-duff
ESM import:
`ts`
import * as pd from "@thi.ng/porter-duff";
Browser ESM import:
`html`
For Node.js REPL:
`js`
const pd = await import("@thi.ng/porter-duff");
Package sizes (brotli'd, pre-treeshake): ESM: 1.03 KB
Note: @thi.ng/api is in _most_ cases a type-only import (not used at runtime)
Two projects in this repo's
/examples
directory are using this package:
| Screenshot | Description | Live demo | Source |
|:-----------------------------------------------------------------------------------------------------------------------|:---------------------------------------------|:---------------------------------------------------|:--------------------------------------------------------------------------------|
|
| Pixel buffer manipulations | Demo | Source |
|
| Port-Duff image compositing / alpha blending | Demo | Source |
`ts
import * as pd from "@thi.ng/porter-duff";
// packed int version (premultiplied ARGB)
pd.SRC_OVER_I(0x80800000, 0xcc0cc00)
// automatically premultiply inputs & post-multiply result
pd.porterDuffPInt(pd.SRC_OVER_I, 0x80ff0000, 0xcc00ff00);
// the above is same as:
pd.postmultiplyInt(
pd.SRC_OVER_I(
pd.premultiplyInt(0x80ff0000),
pd.premultiplyInt(0xcc00ff00)
)
)
// premultiplied float version [R,G,B,A]
pd.SRC_OVER_F([1, 0, 0, 0.5], [0, 1, 0, 0.8]);
`
Integer operators are suffixed with _I, float versions with _F.
Consult above diagram for expected results.
- CLEARSRC
- DEST
- SRC_OVER
- DEST_OVER
- SRC_IN
- DEST_IN
- SRC_OUT
- DEST_OUT
- SRC_ATOP
- DEST_ATOP
- XOR
- PLUS
-
New operators (e.g. for blend modes) can be easily defined via
porterDuff / porterDuffInt. Both functions take 2 function arguments
to extract blend coefficients from the src & dest colors:
`ts
import { porterDuffInt } from "@thi.ng/porter-duff";
// coefficient functions take the normalized alpha values
// of both colors as arguments, but unused here...
const customOp = porterDuffInt(() => -0.5, () => 1);
`
The following coefficient functions are included by default (and are
used by all standard operators):
- ZERO => 0ONE
- => 1A
- => alpha of src colorB
- => alpha of dest colorONE_MINUS_A
- => 1 - alpha of src colorONE_MINUS_B
- => 1 - alpha of dest color
The following modifiers are also discussed in the original Porter-Duff paper (linked above).
- darken / darkenIntdissolve
- / dissolveIntopacity
- / opacityInt
All Porter-Duff operators expect colors with pre-multiplied alpha.
Premultiplication is also recommended for transparent WebGL textures
(especially when using mipmaps). For that purpose the following helpers
might be useful:
- premultiply / premultiplyIntpostmultiply
- / postmultiplyIntisPremultiplied
- / isPremultipliedInt
Furthermore, existing PD operators can be wrapped with automatic
pre/post-multiplies using porterDuffP / porterDuffPInt (see example
above).
Note: HTML Canvas ImageData is using non-premultiplied colors.
If this project contributes to an academic publication, please cite it as:
`bibtex``
@misc{thing-porter-duff,
title = "@thi.ng/porter-duff",
author = "Karsten Schmidt",
note = "https://thi.ng/porter-duff",
year = 2018
}
© 2018 - 2026 Karsten Schmidt // Apache License 2.0