![@thi.ng/porter-duff](https://media.thi.ng/umbrella/banners-20230807/thing-porter-duff.svg?3ece97c3)
![Mastodon Follow](https://img.shields.io/mastodon/follow/109331703950160316?domain=https%3A%2F%2Fmastodon.thi.ng&style=social)
[!NOTE]
This is one of 201 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
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.
References
Status
STABLE - used in production
Search or submit any issues for this package
Related packages
Installation
yarn add @thi.ng/porter-duff
ESM import:
import * as pd from "@thi.ng/porter-duff";
Browser ESM import:
<script type="module" src="https://esm.run/@thi.ng/porter-duff"></script>
JSDelivr documentation
For Node.js REPL:
const pd = await import("@thi.ng/porter-duff");
Package sizes (brotli'd, pre-treeshake): ESM: 1.03 KB
Dependencies
Note: @thi.ng/api is in most cases a type-only import (not used at runtime)
Usage examples
Two projects in this repo's
/examples
directory are using this package:
Screenshot | Description | Live demo | Source |
---|
![](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/pixel/pixel-basics.png) | Pixel buffer manipulations | Demo | Source |
![](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/porter-duff/porter-duff2.png) | Port-Duff image compositing / alpha blending | Demo | Source |
API
Generated API docs
Basic usage
import * as pd from "@thi.ng/porter-duff";
pd.SRC_OVER_I(0x80800000, 0xcc0cc00)
pd.porterDuffPInt(pd.SRC_OVER_I, 0x80ff0000, 0xcc00ff00);
pd.postmultiplyInt(
pd.SRC_OVER_I(
pd.premultiplyInt(0x80ff0000),
pd.premultiplyInt(0xcc00ff00)
)
)
pd.SRC_OVER_F([1, 0, 0, 0.5], [0, 1, 0, 0.8]);
Operators
Integer operators are suffixed with _I
, float versions with _F
.
Consult above diagram for expected results.
CLEAR
SRC
DEST
SRC_OVER
DEST_OVER
SRC_IN
DEST_IN
SRC_OUT
DEST_OUT
SRC_ATOP
DEST_ATOP
XOR
PLUS
Custom operators
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:
import { porterDuffInt } from "@thi.ng/porter-duff";
const customOp = porterDuffInt(() => -0.5, () => 1);
![custom operator](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/porter-duff/porter-duff-custom.png)
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
Additional operators / modifiers
The following modifiers are also discussed in the original Porter-Duff paper (linked above).
darken
/ darkenInt
dissolve
/ dissolveInt
opacity
/ opacityInt
Pre/post-multiplied colors
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
/ premultiplyInt
postmultiply
/ postmultiplyInt
isPremultiplied
/ 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.
Authors
If this project contributes to an academic publication, please cite it as:
@misc{thing-porter-duff,
title = "@thi.ng/porter-duff",
author = "Karsten Schmidt",
note = "https://thi.ng/porter-duff",
year = 2018
}
License
© 2018 - 2025 Karsten Schmidt // Apache License 2.0