Package Exports
- @thi.ng/blurhash
- @thi.ng/blurhash/decode
- @thi.ng/blurhash/encode
Readme
[!IMPORTANT] ‼️ Announcing the thi.ng user survey 2024 📋
Please participate in the survey here!
(open until end of February)To achieve a better sample size, I'd highly appreciate if you could circulate the link to this survey in your own networks.
[!NOTE] This is one of 190 standalone projects, maintained as part of the @thi.ng/umbrella monorepo and anti-framework.
🚀 Help me to work full-time on these projects by sponsoring me on GitHub. Thank you! ❤️
About
Fast, optimized TS implementation of the Wolt Blurhash algorithm.
- https://blurha.sh/
- https://github.com/woltapp/blurhash
- https://github.com/woltapp/blurhash/blob/master/Algorithm.md
This implementation is principally based on the official TypeScript version of the above repo, but in addition to API extensions, the algorithm has been refactored & optimized in several fundamental ways, including:
- massive caching & reduction of repeated cosine calculations in both encoder/decoder
- reduction of internal allocations
- approximation of gamma conversion hotspot (the slightly lower precision is negligible for this use case)
- reading & writing of 32bit pixel data (i.e. using
Uint32Arrayvs.Uint8ClampedArray)
On Firefox 122 (MBP M1 2021), these changes result in ~1.6x faster encoding and ~2.3x faster decoding performance...
Status
ALPHA - bleeding edge / work-in-progress
Search or submit any issues for this package
Installation
yarn add @thi.ng/blurhashES module import:
<script type="module" src="https://cdn.skypack.dev/@thi.ng/blurhash"></script>For Node.js REPL:
const blurhash = await import("@thi.ng/blurhash");Package sizes (brotli'd, pre-treeshake): ESM: 1.21 KB
Dependencies
Usage examples
One project in this repo's /examples directory is using this package:
| Screenshot | Description | Live demo | Source |
|---|---|---|---|
![]() |
Interactive & reactive image blurhash generator | Demo | Source |
API
import { encodeFromImage, decodeToCanvas } from "@thi.ng/blurhash";
import { imagePromise } from "@thi.ng/pixel";
// obtain image data in 32bit ABGR format
// (little endian byte order, same as canvas image data)
const pixels = new Uint32Array(...);
// compute hash
// default detail = 4 (must be in [1,9] range)
const hash = encode(pixels, imgW, imgH, 4, 4);
// "ChD9#TE7NFt6k]WCnhbc"
// in browser env you can encode directly from an
// HTML image or canvas element, see API docs for options
import { imagePromise } from "@thi.ng/pixel";
const hash = encodeFromImage(await imagePromise("test.jpg"));
const hash = encodeFromCanvas(canvas, 4, 4);
// decode to a raw 32bit ABGR pixel array (with optional contrast param)
const pixels = decode(hash, 32, 32, 1);
// decode hash to a new canvas element (optionally attach it to DOM)
const canvas = decodeToCanvas(hash, 32, 32, 1, document.body);
// use CSS to stretch
canvas.style.width = "320px";
canvas.style.height = "240px";Authors
If this project contributes to an academic publication, please cite it as:
@misc{thing-blurhash,
title = "@thi.ng/blurhash",
author = "Karsten Schmidt",
note = "https://thi.ng/blurhash",
year = 2023
}License
© 2023 - 2024 Karsten Schmidt // Apache License 2.0
